OmniAICreator/Qiita-1.07M huggingface dataset:
シークレットマネージャを使ってCloud Composerで機密情報を扱う

# 背景
Cloud Composer の機密情報を扱い際に[Cloud Key Management Service](https://cloud.google.com/kms/docs)を利用しようとしたが、scheduler上でうまく動かなかった。[Secret Manager](https://cloud.google.com/secret-manager?hl=ja)を使って機密情報管理をできるか検証したのでその時のメモ。

# 結論
(追記) Cloud Composer no shedulerで呼び出すように定義する場合、PERMISSIONエラーになるので注意。使う場合はworkerから呼び出されるように定義する。

Cloud Composerでは [`import secretmanager` を使った実装](https://cloud.google.com/secret-manager/docs/reference/libraries?authuser=1)がうまくいかないので、 [`import secretmanager_v1beta1` を使った実装](https://googleapis.dev/python/secretmanager/latest/gapic/v1beta1/api.html)をする 

# クイックスタートで雰囲気掴む
####[クイックスタート](https://cloud.google.com/secret-manager/docs/quickstart?authuser=1)

コンソールで機密情報を `secret_id` と `version` と一緒に登録する。
手元のpythonでクイックスタート動かしたら、登録した機密情報をpythonコードで取得できた。
`pip install google-cloud-secret-manager` が必要。
ここでは、 `import secretmanager` で動かした。

```py

from google.cloud import secretmanager
client = secretmanager.SecretManagerServiceClient()
name = "projects/PROJECT/secrets/SECRET_ID/versions/VERSION"
response = client.access_secret_version(request={"name": name})
payload = response.payload.data.decode("UTF-8")
print("Plaintext: {}".format(payload))
```

# クイックスタートを参考にCloud Composerで実装すると動かない問題
クイックスタートのコードを参考にCloudComposerで実装したところ以下のようなエラーとなった。
Cloud Composerのイメージを `composer-1.13.0-airflow-1.10.12` にあげてもダメ。
`google-cloud-secret-manager` ライブラリのバージョンも最新の `2.0.0`だった。
謎。

```
[2020-11-27 07:12:07,912] {base_task_runner.py:113} INFO - Job 255765: Subtask test     response = client.access_secret_version(request={"name": name})
[2020-11-27 07:12:07,912] {base_task_runner.py:113} INFO - Job 255765: Subtask test TypeError: access_secret_version() got an unexpected keyword argument 'request'
```

# import secretmanager じゃなくて import secretmanager_v1beta1 で実装すると動く
### [Client for Secret Manager API](https://googleapis.dev/python/secretmanager/latest/gapic/v1beta1/api.html)

ググったら `import secretmanager_v1beta1` を使っているレファレンスが存在したので、そっちで実装したら動いた。謎。

# 実装


```py:test.py
import airflow
from airflow import DAG
from airflow.operators.python_operator import PythonOperator
from datetime import timedelta
from dependencies import secrets

def test():
    print(secrets.get('secret_id', "1"))

default_args = {
    "owner": "airflow",
    "depends_on_past": False,
    "start_date": airflow.utils.dates.days_ago(1),
    "execution_timeout": timedelta(minutes=30),
}

dag = DAG("test", default_args=default_args, catchup=False, schedule_interval="0 0 * * *")
PythonOperator(task_id='test', python_callable=test, dag=dag,)
```


```py:dependencies/secrets.py
from google.cloud import secretmanager_v1beta1
from dependencies import const

def get(secret_id, version):
    client = secretmanager_v1beta1.SecretManagerServiceClient()
    name = client.secret_version_path(const.PROJECT, secret_id, version)
    response = client.access_secret_version(name)
    return response.payload.data.decode("UTF-8")

```
WebStormでDeno開発の初期設定手順

2020年のjig.jpインターンのメンターをしていましたninja03です。

今年のインターンでは開発に使った言語はDenoでした。
メンバーは主にVisual Studio Code(VSCode)を使いました。

自分は仕事ではJetBrains社のJava用開発環境の[InteliJ IDEA](https://www.jetbrains.com/ja-jp/idea/)を使っています。
そのためDenoの開発には操作方法が近い同社のJavaScript用開発環境の[WebStorm](https://www.jetbrains.com/ja-jp/webstorm/)を使っています。

WebStormは有料で価格は月額680円ですが、30日間の体験版があります。
また学生だと無料ライセンスが取得できるのでそのあとも引き続き使うことができます。
https://blog.jetbrains.com/ja/2019/08/22/2105/

WebStormでも開発をしてみたい方向けに、初期設定方法を解説していきます。

# Denoのインストール
まずはVSCodeと同様にDenoをインストールします。

WindowsキーとRキーを同時に押し「ファイル名を指定して実行」を開きます。
```powershell```と入力してPowerShellを開きます。

Denoのインストールコマンドを入力し実行します。
https://deno.land/manual/getting_started/installation

```powershell
iwr https://deno.land/x/install/install.ps1 -useb | iex!
```

# WebStormのインストール
下のリンクからWebStormをダウンロードします。
https://www.jetbrains.com/ja-jp/webstorm/
ダウンロードしたインストーラーを起動します。
特に設定せずに```Next```→```Next```→```Finish```でインストールが完了します。

# Pleiadesで日本語化
下のリンクから```pleiades-win.zip```をダウンロードします。
https://mergedoc.osdn.jp/#pleiades.html#PLUGIN
解凍して、```setup.exe```を起動します。
```日本語化するアプリケーション```→```選択```を押します。
```C:\Program Files\JetBrains\WebStorm 2020.2.3\webstorm64.exe```
を選択します。
```日本語化する```を押して完了です。

# Denoプラグインのインストール
WebStormにDeno開発で使うプラグインをインストールします。
まずWebStormを起動して```新規プロジェクト```→```空のプロジェクト```→```作成```を行います。
メニューバーから```ファイル```→```設定```→```プラグイン```→```マーケットプレース```を開きます。
```Deno```で検索してインストールをします。

# インデントの設定
メンバーとインデント数を合わせる必要がある場合に変更します。
メニューバーから```ファイル```→```設定```→```エディター```→```コードスタイル```→```JavaScript```→```タブとインデント```を選びます。
```タブサイズ``` ```インデント``` ```連続インデント```の文字数を変更します。

# コンソールの文字化けの解消
WebStormで```console.log("サーバ起動")```のように日本語を出力するとコンソールで文字化けします。
```ヘルプ```→```カスタムVMオプションの編集```を開いて以下の文をファイルの最後に追加します。

```
-Dfile.encoding=UTF-8
```
その後、WebStormを再起動すれば文字化けしなくなります。

# サンプルプログラムの実行
Denoのサーバプログラムを動かしてみます。
メニューバーから```ファイル```→```新規作成```→```JavaScriptファイル```を選び、main.jsを作成します。
下のプログラムを入力します。

```javascript
import {serve} from "https://deno.land/std/http/server.ts";

const s = serve({port: 80});
console.log("サーバー起動");
for await (const req of s) {
  const json = {
    msg: "ハローワールド"
  };
  req.respond({
    status: 200,
    headers: new Headers({"content-type": "application/json"}),
    body: JSON.stringify(json)
  });
}
```
すると、```Enable Deno support for this project?```
と上に出るので```はい```を押します。

ソース上で右クリックします。
```'Deno: server.js'の編集...```を押します。
引数が```run```になっているのを```run -A```に変更します。

再度ソース上で右クリックします。
```実行 'Deno：server.js'```をクリックするとサーバプログラムが起動します。

ブラウザで、```http://localhost:8888/```を開くと結果を確認することができます。

ソースを書き換えたら右クリックし```実行 'Deno：server.js'```を押すとプログラムがリロードされます。

#.gitignoreの設定
WebStormが作るファイルをGitのコミットから除外するとコミットしやすくなります。
下の文を.gitignoreファイルに書いておきます。

```
.idea/*
```
JavaScriptでコラッツ予想の動作を実行

# コラッツ予想の動作を確認してみる

JavaScriptでコラッツ予想の動作を実行するプログラムを作成してみました。

・自然数を入力する
・「偶数なら2で割り、奇数なら3倍して1を足す」という操作を繰り返す
・1になったら終了する

上記操作で必ず1になってプログラムが停止する、というのが「[コラッツ予想](https://ja.wikipedia.org/wiki/%E3%82%B3%E3%83%A9%E3%83%83%E3%83%84%E3%81%AE%E5%95%8F%E9%A1%8C)」です。
「予想」と呼ばれるとおり、2020年現在証明はされていません。

![コラッツ予想.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/513949/05803274-7c9d-25f3-0ffc-0d3d5f2e1323.png)


```html:CollatzProblem.html
<html>
<head>
  <meta http-equiv="Content-Type" context="text/html; charset=UTF-8" />
  <meta charset="UTF-8" />
  <title>JavaScriptでコラッツ予想</title>
<script>

function doCalc() {
	var txtN1 = document.getElementById("txtN1");

	var n1, n2, strResult;
	var vWork = [];
	var vOut = [];

	n1 = parseInt(txtN1.value, 10);
	n2 = n1;

	vOut.push("" + n1);

	while (1) {
		if (n2 <= 1) { break; }

		if (n2 % 2 == 0) {
			n1 = n2
			n2 = n2 / 2;
			strResult = "" + n1 + " / 2 = " + n2;
			vOut.push(strResult);
		} else {
			n1 = n2
			n2 = n2 * 3 + 1;
			strResult = "" + n1 + " * 3 + 1 = " + n2;
			vOut.push(strResult);
		}
	}

	document.getElementById("result").innerHTML = vOut.join("\n");
}

</script>
</head>
<body>

<h2>コラッツ予想</h2>

<ul>
<li>自然数を入力する</li>
<li>「偶数なら2で割り、奇数なら3倍して1を足す」という操作を繰り返す</li>
<li>1になったら終了する</li>
</ul>

4桁 まで
<input type="text" id="txtN1" value="" maxlength="4" size="7" oninput="value = value.replace(/[^0-9]+/i,'');" />
<input type="button" value="計算" onclick="doCalc()" /><br />
<br />

<textarea id="result" rows="50" col="20" style="width:700px;height:400px;">
</textarea>

</body>
</html>
```
フリーの３次元復元(Structure from motion)ソフトの比較！2020年12月版

#はじめに
「はー、復元したい...でもソフトウェアってすぐ使えなくてマイッチング。使えるかどうかわからないソフトを買うのも気が進まないし...。ただで簡単に使える３次元復元のいいソフトがあればなあ...。」
とお悩みの素敵な貴女。いいでしょう、そのお悩み、解決いたしましょう。

#結論
簡単にインストールしてすぐ使いたい人、中身のプロセスを理解したい人 → [Meshroom](https://alicevision.org/#meshroom)
ちょっとインストールに時間がかかっても精度がいいものが欲しい人　→　[COLMAP](https://colmap.github.io/)
精度のみが問題の人　→　[こちらの評価サイト](https://www.tanksandtemples.org/leaderboard/)で最新の手法をとってきてbuild

#比較結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/753103/8c5b6779-cb50-0d18-526b-520d25b62cab.png)
[比較表](https://docs.google.com/spreadsheets/d/14Rh27g1Zv9KZ-nBeDgNYJ8nw1uPXLnN40ODKAZBziIY/edit?usp=sharing)

#まとめ
いかがでしたでしょうか？~~この記事執筆に全く時間をかけていないっぷり。~~
皆様の読む時間削減を考え、シンプルにしてみました。
お気に召された方はfollowをお願いします。(followってあるんでしたっけ？)
spase-checkoutコマンド メモ書き

sparse-checkoutコマンドは Git 1.7 でリリースされているようですが、
「Git 2.26」で使うことをオススメします。
※ `sparse-checkout add` コマンドは **Git 2.26** で追加されています。

## 初期化
```
git sparse-checkout init
```
- sparse-checkoutを有効にする
- 設定ファイルが無い場合、作成する (上書きはしない)

設定ファイルの中身

```
/*
!/*/
```

## 設定内容を確認する
```
git sparse-checkout list
```

## 設定を更新する
```
git sparse-checkout set AAA BBB CCC
```
- sparse-checkoutを有効にする
- 設定ファイルが無かったら、コマンド引数の内容で作成する
- 既に設定ファイルがある場合、中身を上書きする

設定ファイルの中身

```
AAA
BBB
CCC
```

## 設定を追加する
```
git sparse-checkout add AAA BBB CCC
```
- 設定ファイルの末尾にコマンド引数の内容を足す


`.git/info/sparse-checkout` を編集すれば良い話なのでわざわざコマンドを使わずともいいような。。
Airtestを使ったAndroidアプリの自動操作

## はじめに
ソフトウェアテストの業界向けに役に立つ話、第一回目です。
**Airtest IDE**というUI自動化ソフトウェアを使用して、Androidアプリのかんたんな自動化をしてみました。
<img width="100" alt="スマホを持つ猫" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618790/5255d32a-a992-a69f-3281-3eb872aeae5f.png">

## 1. Airtestをダウンロード
Airtest Projects
https://airtest.netease.com/

公式サイトからソフトウェアをダウンロードし、インストールします。

## 2. 起動
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618790/56d6c8e3-755b-897f-bd85-7c49e75c520e.png" width="300">
ソフトウェアを起動すると、ログインを求められますが「Skip」しても問題ないようです。

## 3. 新規作成
メニューバーから「File」>「New」>「.air Airtest Project」を選択し、新規のプロジェクトを作成します。
![スクリーンショット 2020-12-01 17.35.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618790/9674a886-ad74-a157-84b2-07982bcbd608.png)

## 4. スマホの接続
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618790/f96b01a2-af46-37d9-cf2b-e57a3af1f8b7.png" width="200">
スマホをPCと接続し、右側の「Devices」にある「refresh ADB」を押します。すると、デバイス名が表示されますので、「connect」ボタンを押して接続します。

接続の際に以下の操作が事前に必要です。

- Android開発者向けオプションが「ON」になっている
- USBデバッグが「ON」になっている

## 5. テストアプリをインストールする
https://github.com/AirtestProject/Airtest/tree/master/playground/blackjack_example

今回はAirtestのGitHubにあるブラックジャックのサンプルアプリ「blackjack-release-signed.apk」をインストールしてみました。

## 6. タッチしたい箇所を選択する
![test2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618790/0acdcf48-999a-1cc7-e1f9-db131a1c478d.gif)
ツールボックスにある「touch」のボタンを押し、タッチしたい箇所をドラッグして切り取ります。すると、コードが自動的に生成されます。

## 7. 一連の操作を書く
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618790/e73956b6-7926-4497-4b65-a27e204929b6.png" width="400">
コードはPythonで記述するようです。今回は以下のような一連の操作を書きました。

1. スタートボタンを押す
2. 掛け金をベットする
3. ブラックジャックを開始する
4. カードを交換しない
5. 勝利だったら、タイトル画面へ　それ以外はもう一度プレイする

## 結果
![test.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618790/3152817a-ca9b-2a7b-9772-d1712a623994.gif)
勝利するまで、ゲームを自動で続けてくれました。:clap:

## さいごに
スマートフォンのアプリゲームでは、バトルがオートで行えることが多いのでさまざまなタイトルで活用できるかと思います。自社開発したアプリゲームのテストなどで参考にしていただければと思います。
Fargateのキャパシティープロバイダー戦略

## Fargateでもスポットインスタンスを使う
fargateでオートスケールの際に「費用削減したい」との要望があり、スポットインスタンスを使うことにした。

## キャパシティプロバイダーを設定する

|タイプ  |base  |weight  |
|---|---|---|
|FARGATE_SPOT  |1  |5  |
|FARGATE  |2  |2 |

この場合は､最初にFARGATEが2台､FARGATE_SPOTが1台起動する｡AutoScaleによって増える場合は､
FARGATE:FARGATE_SPOT=2:5の割合で増える｡

|タイプ  |スタート時の台数  |AutoScaleで7台構成になった場合  |
|---|---|---|
|FARGATE_SPOT  |1台  |5台  |
|FARGATE  |2台  |2台 |

設定を行う｡

```
aws ecs put-cluster-capacity-providers \
     --cluster [クラスター名] \
     --capacity-providers FARGATE FARGATE_SPOT \
     --default-capacity-provider-strategy capacityProvider=FARGATE_SPOT,weight=5,base=1 capacityProvider=FARGATE,weight=1,base=2
```


## サービスへの登録
```
$ aws ecs create-service \
--cluster web-cluster \
--service-name web-prod \
--launch-type "FARGATE" \
--capacity-provider-strategy capacityProvider=FARGATE,weight=2,base=2 capacityProvider=FARGATE_SPOT,weight=5,base=1 \
--task-definition gservice-prod \
--network-configuration "awsvpcConfiguration={subnets=[subnet-xxxxx,subnet-yyyyy],securityGroups=[sg-zzzzzz],assignPublicIp=DISABLED}" \
--deployment-configuration maximumPercent=200,minimumHealthyPercent=100 \
--load-balancer targetGroupArn=arn:aws:elasticloadbalancing:ap-northeast-1:xxxxxxxxxxxxx,containerName=gservice,containerPort=9000 \
--desired-count 1
```
【Athena】With句を使って一時テーブルを作成してSQLを簡略化させる

## 複雑なサブクエリ
AthenaでSQLを書いてデータを抽出しているとどうしても複雑なSQLになることが多いです。何度もつかうサブクエリに関してはviewテーブルを作成することも考えられますが、一時的に使うものまでviewテーブルを作成するのは面倒に感じられます。

## With句を使って一時テーブルを作成する
With句のPrestodbのドキュメントは[こちら](https://prestodb.io/docs/current/sql/select.html)です。

例えば以下のSQLを作成したとします。

```sql
SELECT
    t1.*, t2.*
FROM
    (SELECT a, MAX(b) AS b FROM x GROUP BY a) as t1
    INNER JOIN
        (SELECT a, AVG(d) AS d FROM y GROUP BY a) as t2
    ON  t1.a = t2.a
```

サブクエリで取得しているテーブルをWith句で書くと処理がSQLスッキリします。

```sql
WITH
  t1 AS (SELECT a, MAX(b) AS b FROM x GROUP BY a),
  t2 AS (SELECT a, AVG(d) AS d FROM y GROUP BY a)

SELECT t1.*, t2.*
FROM t1
INNER JOIN t2 ON t1.a = t2.a;
```

スッキリするだけでなく、複数回同じサブクエリが登場するときはそのまま使いまわしも可能、サブクエリの条件が変わったときもWith句の変更のみで済むため、変更漏れのリスクが避けられます。
With句は非常に便利なので使えることだけでも覚えておくと良いと思います。
【Swift】基本的な型の紹介〜Optional型〜

#Optional\<Wrapped>型 とは

Optional\<Wrapped>型とは、値が存在するか空かのいずれかを表す型です。

swiftでは基本的にnilを許容しないですが、
**nilを許容する必要がある場合は**Optional\<Wrapped>型を利用します。

Optional\<Wrapped>型のWrappedとは
プレースホルダ型と言い実際にはWrappedを具体的なInt型やString型に置き換えて使用します。

Optional\<Wrapped>のように\<>の中にプレースホルダ型を持つ型を**ジェネリック型**と言います。
ジェネリック型については別記事て記載します。

nilを許容する必要がある場合とは、どのような状況か・・・。
twitterのアイコンなどでnilが使えるのではないかなと思います。

twitterのアカウントを作成する際に、
ユーザ名は必須ですが、アイコンは任意だと思います。

その時に、アイコンがnilを許容しない設計だと、
アイコン画像を設定しないといけなくなると思います。

個人的にはそういう時に使うんだろうなーと思いました、

##Optional\<Wrapped>型の作成方法

Optional型の作成方法は二通りあるらしいのですが、
一般的に使用される方しか覚えてないのでそちらを共有します。

Optional型には、Optional型と、非Optional型があります。
Optional\<Wrapped>型を作成する方法はものすごく簡単で、！や？を付けるだけです。


```swift

var a: Int    // 非Optional型  -> nilを許容しない   
var b: Int?   // Optional<Int>型  -> nilを許容する  
```
変数aは、いつも通りの宣言ですね。
変数aには何か値を代入して初期化しないとコンパイルエラーがおきます。

しかし、変数bはOptional型でnilを許容するので
初期化しなくてもコンパイルエラーは起きません。

つまり、変数aはコンパイルエラー、変数bはnilという状態になります。

！や？を語尾に付けるだけでnilを許容するようになるなんてOptionalは便利だ！
と思いますが、実は面倒な部分があります。

```swift

var a: Int?   // Optional型

//print関数でログ出力
print(a)   // nil
//type関数で変数aの型を表示
type(of:a)   // Optional<Int>
```
まだ何も代入していないので、print() でnilが返されるのは想定内ですが、
変数aは、Int型かと思いきやOptional\<Int>型になります。

```swift

var a: Int?   // Optional型
a = 1

//print関数でログ出力
print(a)   // Optional(1)
//type関数で変数aの型を表示
type(of:a)   // Optional<Int>
```

さらに、変数aに１を代入すると、
print()関数の結果がOptional(1)
type()関数の結果がOptional\<Int>

**Optionalってなんぞや！！**

当時は訳が分からず5回ぐらい叫びました(笑)

まず、Optional型というのは、nilを許容する型です。
なので１を代入したとしてもまたどこかでnilが代入される可能性があります。

そのような不確かなものをswift様が許す訳もなく、
Int型と同じくくりにせずOptional\<Int>としているっぽいです。

なので、Int型とOptional\<Int>型の計算は、もちろん出来ません。

```swift

var a: Int = 10   // Int型
var b: Int? = 100   // Optional<Int>型

var c = a + b   // 10 + Optional(100)  -> コンパイルエラー
```

nilを許容出来るようにするのは便利ですが、
このようにOptional型は通常では使えなくなっております。

では、どのようにしてOptional型を扱うのか。
Optional型で宣言した変数はずっと使えないのでは不便です。

しかし解決策があります。
それは、Optional型の**アンラップ**です。

Optional型の変数をアンラップすることにより、
通常のInt型やString型と同じように利用できます。

今回はOptional型の紹介ですので、
アンラップについては別の記事に記載します。

そちらをご覧いただけると幸いです。

以上、ありがとうございました！
実際に発生したSVGを利用したXSSについて

この記事は [WESEEK Advent Calendar 2020](https://qiita.com/advent-calendar/2020/weseek) 1日目の記事です。

# SVGを利用したXSS

## 概要
[GROWI](https://growi.org/ja/) で存在していた脆弱性。
**SVG を利用した XSS** を元にその仕組みと解決方法をまとめます。

## 前提知識
SVG は画像を記述する XML ファイルです。
一般的な PNG や GIF、 Javascript を埋め込むことが可能です。  

埋め込んだ Javascript が実行されるのは画像が表示されるタイミングです。

### 参考
[SVGとは](https://tips.weseek.co.jp/5e393124e848c600487d69f3)

## 今回報告された脆弱性
SVG は、img タグを使用して表示する限りは画像として扱われます。
そのため、動的に SVG のスタイルを変更させることはできませんが、 悪意のあるスクリプトを防ぐことが可能です。

GROWI では、 ページに添付された SVG ファイルは SVG として DB 上に保存されますが、
レンダリングされる時は img タグを使用します。
![5fbe787f36ac6300497c222a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/394488/62233292-b38b-5c8f-bc4e-23a27bd488b9.png)
そのため、ページを閲覧するだけであれば 悪意のあるスクリプトは実行されません。  

しかし、添付された AttachmentID を使用した url、 https://tips.weseek.co.jp/attachment/5fbe7a0736ac6300497c224e にアクセスすることで、SVG をブラウザに直接表示することが可能です。
![5fbe86ea36ac6300497c2349.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/394488/8b20d142-0d57-f61c-bafc-0436fa493993.png)
(AttachmentID を知らなくても、添付データ一覧のリンクを押すことで上記の url にアクセスされます。)

SVG を直接表示すると埋め込まれたスクリプトが実行されてしまいます。
過去の GROWI では、直接表示された SVG のスクリプトを対策していなかったため、脆弱性として報告されました。

## 対策方法
- [実際に施した変更(GitHubに飛びます)](https://github.com/weseek/growi/pull/2688/files)

対策方法として、 CSP の script-src に unsafe-hashes を指定する方法を取りました。
unsafe-hashes によって指定された hash 値以外のハッシュ値をもつスクリプトの実行を防げます。

hash 値を一切指定していないため、全てのスクリプトを防ぐことになります。
もし、ユーザーが意図的に script を実行したければ、 addEventListener を使う必要があります。


### 参考
- [コンテンツセキュリティポリシー (CSP)](https://developer.mozilla.org/ja/docs/Web/HTTP/CSP)
- [The unsafe-hashes Source List Keyword](https://content-security-policy.com/unsafe-hashes/)

## まとめ
報告をいただいた脆弱性は [JVN#56450373
GROWI における複数の脆弱性](https://jvn.jp/jp/JVN56450373/index.html) にて対策方法と共に公開されました。  
対策として、v4.1.5 以降のバージョンへのアップデートを推奨しております。

今回の脆弱性は、SVG のアップロードをする必要があるため、アップロードの権限を持たない外部のユーザーが脆弱性を利用して攻撃することはできませんが、典型的な XSS として良い例だと思います。

※この記事は [WESEEK Tips wiki](https://tips.weseek.co.jp/) に 2020/11/26 に投稿された記事の転載です。
Tips wiki では、IT企業の技術的な情報やプロジェクトの情報を公開可能な範囲で公開してます。

## 参考資料
https://digi.ninja/blog/svg_xss.php
【Vuetify】vuetifyのソースをブラウザで確認する方法【自分用】

はじめてvuetifyを触ってみましたがgithubからソースcloneしてみた際にまずこれどうやってブラウザ表示するの？
ということがあったのでその方法を自分用に簡単にメモ

##ブラウザ表示させるまでのコマンド

作業はDOS窓で行う
package.jsonが存在するディレクトリへ移動後以下のコマンド

```
npm install
```

アプリケーションを起動

```
npm run serve
```


以下のようにURLが表示されるのでこれをブラウザへ入力して完了

```
  App running at:
  - Local:   http://localhost:8080
```
Integromatを使って何でもかんでもGoogle Chromeに通知する

Integromat Advent Calnedar 2020 1日目です。

初日から若干変化球ですが、一番汎用的に使えそうなGoogle Chromeとの連携について紹介します。

IntegromatのGoogle Chrome モジュールでできることはただ一つ。
ブラウザからの通知です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99398/4e667a12-1402-53ff-8c08-2cc3319aaee7.png)


# 使い方
Google Chromeの拡張機能をインストールしておきます。
https://chrome.google.com/webstore/detail/integromat-customizable-e/cfamjaolobgncfhomepbmjjihlbkchgb

IntegromatのシナリオでGoogle Chromeモジュールを追加します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99398/c4a4427c-89e6-aee7-340e-ac3f4bda81aa.png)

Actionは「Send a notification」です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99398/06b37217-42c7-b26e-c068-9d159793888f.png)

モジュール内の設定はシンプルで
Recipientsで「Add this Crhome」をクリックすれば、Google Chrome 拡張機能のRegistration IDが自動で入ります。

URL addressは通知をクリックした時に開かれるURLです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99398/aff38567-158f-0120-7982-4c1d86f74843.png)


PriorityはOS側で通知をどのくらい優先するかの度合いのようです。

「Disable the auto-dismiss of notifications」にチェックを入れると、closeをクリックするまで通知が消えずに残ります。

Collapseにチェックを入れると、Chromeが開かれていない間の通知は
次にChromeを開いた時に一番最新のものだけが通知されます。

全て通知する必要がある場合は、Collapseのチェックを外しておく必要があります。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99398/a2e561a3-94cd-2a1b-7540-8d67aa1a7fa7.png)

#発展編

通知先のChromeは複数設定することができます。

通知を飛ばしたいChromeに拡張機能を入れて画面を開くと、Registration IDが表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99398/6db1e043-8b54-da8f-867a-58b69cd22d25.png)

Recipientsの「Add item」でRegistration IDを追加します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99398/1ee81b5a-acb8-5ad8-8a02-ad73512b7997.png)

Integromatの課金体系はOperations単位になっていますが
1つのモジュールにたくさんRegistrationIDを追加してもOperationsの消費は1つだけですので
課金面でも比較的安心して使えます。

RegistrationIDは一度に1000件まで登録できるみたいなので
チームのメンバー全員に通知するような用途でも問題なく利用できますね。

#使用例

ただ通知するだけなので本当に何にでも使えると思います。

強いて言うなら、自分で閉じない限りは通知が出たままになるよう設定出来るので
すぐに必ずアクションを起こさなければいけない通知に使えそうです。

Integromat公式の紹介ページにいくつかサンプルが載っています。
https://www.integromat.com/en/integrations/chrome

チケットシステムのZendeskでチケットが起票されたら通知や
電話がかかってきたらCRMの登録と照らし合わせて通知は
即時性が高いので相性が良さそうです。

（Androidの電話受発信をトリガーにするシナリオは、今回のAdvent Calendarのどこかで紹介しようと思います。）

#参考
公式ドキュメント
https://support.integromat.com/hc/en-us/articles/360006171574
JSのお仕事　(JSアウトプット2)

##あいさつ
初めての人は初めまして！知っている人はこんにちは！
中学生プログラマーのAtieです！
今回もJSを学んできたのでそのアウトプットをしていきます！
今回は第二回目ですがもし第一回の記事を読んでいなければそちらのほうから読んでいただくとわかりやすいと思います！[なぜJSが必要なのか？　(JS学習アウトプット)](https://qiita.com/Atie_web/items/6e1c19cbdbd9b51b59ca)
今回は「JSのお仕事」ということでJSのお仕事(役割)について学んできました！
それでは！

##前回の復習

従来のweb
- レスポンスがhtml
- ページ全体がレンダリング

現代のweb
- レスポンスがJSON
- 必要なところだけレンダリング
- リッチで使いやすい


#JSのお仕事
JSのお仕事には主に二つあります
一つ目が
###データのやり取り
二つ目が
###DOM操作
です

順に解説していきます

##データのやり取り
ではまずJSの一つ目のお仕事「データのやり取り」についてです
Twitterを例に解説していきます

まずはTwitterのhtmlの構造を見ていきましょう！(この構造とは限りませんし省略してあります)

```home.html
<ul>
    <li>
        <div>
            <img src="~">
        <div>...</div>
        </div>
    </li>
</ul>
```

もし構造がこのようになっているとします
しかしこれだとスクロールすると新しいツイートが表示されないので
スクロールするとJSがwebAPIに「データが欲しいです！」と頼みに行きます
そしてwebAPIがDBなどにアクセスしてデータをとってきてJSに「ほれ！」とデータを渡します
そしてこの時に渡されるデータが「JSON」なのです
JSONについては前回学んだので説明は省きます

それでは渡されたJSONのデータを見てみましょう(これはあくまでも一例です本物のTwitterがこうだとは限りません)

```data.json
{
    "data" : [
        {
            "name": "～～",
            "bady": "～～",
            "src": "～～"
        },
        {
            "name": "～～",
            "bady": "～～",
            "src": "～～"
        },
        {
            "name": "～～",
            "bady": "～～",
            "src": "～～"
        }
    ]
}
```
このようなデータになっていました！
しかしデータを受け取ったところでこのまま表示させるわけにはいきません
読みにくいのでhtmlに変換しますこれを**パース**といいます
パース自体は「解析」という意味で何もhtmlに変換することすべてがパースと呼ぶわけではありません
パースについてですがここからはDOM操作です

##DOM操作
さぁ！先ほどwebAPIからjsonをもらうことができました！
「わーい！」
...
しかしまだ仕事は残っています
先ほど説明しましたがjsonをhtmlに変換して見やすくします
これを**パース**と呼びます

DOM操作の例を見るためにhtmlとjsonのデータを見てみます

```home.js
<li>
    <div>
        <img src="data[0].src">  <!--jsonデータの0番目のsrcのデータがここに入る-->
        <h1>data[0].name</h1>    <!--jsonデータの0番目のnameのデータがここに入る-->
        <p>data[0].bady</p>      <!--jsonデータの0番目のbadyのデータがここに入る-->
    </div>
</li>
```

```data.json
{
    "data" : [
        {
            "name": "～～",
            "bady": "～～",
            "src": "～～"
        },
        {
            "name": "～～",
            "bady": "～～",
            "src": "～～"
        },
        {
            "name": "～～",
            "bady": "～～",
            "src": "～～"
        }
    ]
}
```

htmlにはコメントを書いたのでhtmlファイルとjsonのデータを見比べてみてください
わかりやすいと思います
このようにhtmlをjsonに変換することをパースと呼びましたがこのようなことが**DOM操作**です

パースが終わることで新しいデータが読み込まれ新しい投稿が表示されます

##まとめ
今回のまとめです！

JSのお仕事
- データのやり取り
- DOM操作

データのやり取りではJSがwebAPIにデータを取りに行きます
DOM操作ではとってきたjsonデータをhtmlに変換します(パースします)
この二つが主なJSのお仕事です

データのやり取りには
- 保存する
- ローカルに保存する
- cookie
なども含まれています

DOM操作では
- 追加
- 変更
- 削除
などもしています

##最後に
ここまで読んでいただきありがとうございました
次回は実際にコードを書いてみます！
それでは！また次回に！

[前回](https://qiita.com/Atie_web/items/6e1c19cbdbd9b51b59ca)

[AtieのTwitter](https://twitter.com/Atie_BackendPG)
[しまぶーのIT大学さんのTwitter](https://twitter.com/shimabu_it)
##参考
[【基礎から学ぶ JavaScript 入門 #2】Twitterを例にJavaScriptがどんな働きをするのか理解しよう【ヤフー出身エンジニアが教える初心者向けプログラミング講座】](https://www.youtube.com/watch?v=5U0nAojNQS0)
vscodeでオリジナルのショートカット（スニペット）を登録して，人生の無駄を削減する．

#はじめに
## 背景
　近年，私のアルバイト先で私がポンコツなせいで，変数の中身を確認したい時がよくあります．
`print`を使ってもいいのですが，最近は代わりに`import pdb; pdb.set_trace()`という方法を知りました．大変便利でお世話になるのですが，毎回`import pdb; pdb.set_trace()`と入力するのがだんだん面倒になってきました．
## 目的
そこで，頻繁に入力する決まった表現を短いタイピングで実現することを目標にします．
## 意義
人生の時間が増える．

#方法
1. コード > 基本設定 > ユーザースニペット　を押します．
![スクリーンショット 2020-12-01 17.35.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/455102/0e7a4288-6cff-7914-fc79-5ff44a303fa1.png)

1. 登録したい言語を入力します．
　![スクリーンショット 2020-12-01 17.35.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/455102/c8abcdd8-24a5-c49e-c1e7-29cb8ac76636.png)

1. コメントアウトを外し，以下を入力します．
    - スニペットの名前
    - 入力する短縮キーワード(prefix)
    - 実際に入力されるコード(body)
    - 説明(description)
![スクリーンショット 2020-12-01 17.38.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/455102/8bf7c037-2691-d5ce-79c4-f1b580e988c6.png)

1. prefixを入力すると，候補として上がってきます．

![スクリーンショット 2020-12-01 17.42.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/455102/99303e96-d3d2-95e8-496c-63f283a9a72b.png)


# おわりに
人生から無駄な時間が減ります．
たった一行でできる深層Webの作り方

# はじめに
初投稿です。よろしくおねがいします。
突然ですが皆さんは**深層Web**という言葉を聞いたことがあるでしょうか。おそらく聞いたことのある人にとっては「やばいもの」、「常人には理解できない動画の溜まり場」という印象があると思いますが、一般的には__WorldWideWeb(WWW)にある情報のうち、通常の検索でヒットされることのないもの__のことを指します。要するに会員制のページとか社内ツールなんかもすべて深層Webということですね。
そんな深層Webですが、実は__HTMLにたった一行コードを追加するだけで簡単に作成することが可能__です。今回はその方法についていい感じに説明していこうと思います。
# その前にちょっと前ふり
深層Webの作り方について説明する前に、まずは検索エンジン(ここではGoogleを例とする)がどうやって情報を収集しているのかについて掘り下げて見ましょう。
一般的に検索エンジンはデータを収集する際、__クローラー__というプログラムを用いています。検索エンジンにおけるクローラーはWWWを巡回し、未知の情報を見つけたらそれをデータベースに登録、既知の情報が存在しないことを確認したらそれをデータベースから削除という処理を常に行っており、これによって膨大な量の情報を管理しています。
その後、検索エンジンはクローラーを用いて得た情報に対して査定を行います。査定の基準については本記事では省略しますが、それによって高い評価を得たページほど優先されて検索結果に表示されるという仕組みになっています。まとめると、
1. クローラーを用いてWWWを巡回
2. 巡回によって得た情報を基にデータベースを更新
3. 情報に対して査定を行い、評価の高いページを優先的に検索結果に表示
という3ステップによって検索エンジンの動作は成り立っています。
# 本題
検索エンジンの仕組みについて理解したところで、いよいよ本題に入っていきます。
とはいっても深層Webを作成する方法はいたって簡単で、HTMLの`<head>~</head>`内に以下のようなタグを追加するだけです。

```html:deepweb.html
<head>
~~~中略~~~
<meta name="robots" content="noindex,nofollow">
~~~中略~~~
</head>
```
この中でも重要なcontent内のnoindex,nofollowについて解説していきます。
## 解説1
noindexタグは、__前述の検索エンジンの仕組みを2番目の段階で打ち止めにする__効果があります。2番目の段階で打ち止めにされるということは、3番目に行われるはずのページの査定が行われなくなり、結果として検索結果への表示を防ぐことができます。なお、noindexタグのついたページは検索エンジンからの評価の対象外になるだけで__クローラーからの巡回そのものの対象外になるわけではない__ということに注意してください。
## 解説2
nofollowタグはどちらかというとSEO対策に用いることが本来の使い方ですが一応解説します。
例えば、"noindexタグのついたページAとnoindexタグのついていないページBがあり、ページBは内部でページAを引用している"と仮定します。このとき、ページBが検索エンジンから低い評価を受けてしまうと、__巻き添えでページAも低い評価を受けてしまう__ことがあります。ここで対策として用いられるのがnofollowタグであり、引用先に指定したページの評価による影響をなくすことができます。
#最後に
不適切な箇所などがあれば~~どうか許してください~~コメント等で指摘をお願いします。
【JS】配列やオブジェクトは比較できない？比較できる場合とできない場合。

配列やオブジェクトの要素同士を比較するときの注意点メモ。

##個別に定義した場合は比較できない
配列やオブジェクトの中身の値が同じでも、等価式にするとfalseになる。

**▼配列同士の比較**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/90661788-87cd-5ff8-cc5a-9c29091356c1.png)

**▼２次元配列の場合**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/e953ff37-c5c9-ee42-4315-a7f60248fde4.png)

**▼オブジェクトの場合**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/747b1371-3bc0-d79e-dacd-700e054caa97.png)

**▼配列内のオブジェクトの場合**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/4275ad8a-be03-a046-4974-829055484dcb.png)

いずれの場合も見た目は完全に一致してるが、評価結果はことごとくfalseになる。

これは、各配列の要素を指すポインタが異なる場所を示しているため。



<br>
##比較可能な場合
元の配列やオブジェクトの要素を参照した場合は比較が可能になる。

**▼配列の場合**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/53c083a3-1d60-362e-045f-40ca58a79bb8.png)


**▼オブジェクトの場合**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/6cfa544a-2860-747c-5409-3226c0f9d107.png)




<br>
##filterの応用
上記の結果とfilterを使うと、必要な要素のみ残したり、除外したりすることができる。

例えば除外する場合は以下のようになる。

**▼配列の場合**

|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/8328af3f-164a-9e7f-3835-5acdc7c31540.png)|
|:--|


<br>
**▼オブジェクトの場合**

|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/fcfaee01-d7ed-7953-48f6-bd87b068af97.png)|
|:--|


<br>
配列やオブジェクトの要素をごっそりフィルタリングしたい場合は評価式の評価対象に注意が必要。
卒論のために，オリジナルのNN（ニューラルネットワーク）をいい感じに可視化する．

#卒論のために，オリジナルのNN（ニューラルネットワーク）をいい感じに可視化する．

# これ
http://alexlenail.me/NN-SVG/LeNet.html
こんなんとか↓
![スクリーンショット 2020-12-01 17.24.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/455102/4a3bdc71-0c94-2af4-7a35-98dc5f29aae3.png)

こんなんとか↓
![スクリーンショット 2020-12-01 17.24.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/455102/de6ae937-8872-69cd-9b5c-516af9be7237.png)

こんなんとか↓
![スクリーンショット 2020-12-01 17.24.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/455102/6aceb696-9c18-48e6-08cf-0beb25bc252c.png)

が自由自在．でも，ちょっと作るのは大変．
大学の先生がTwitterで教えてくれました．
【メモ】WSL2でGUIを使うために

# 背景
WSL2 で X11 を使いたかったが、紹介されている方法でどうにもうまく接続できなかった。皆さん nameserver でいけるようですが、私のは何故かダメ。

# 解法
ホストのIPv4アドレスを指定すれば良さそうだったので、次のようにした。
まず ifconfig を使いたいので、インストール。

```
sudo apt-get install net-tools
```

次に下記を .bashrc に書き込むと毎度 export コマンドを実行しなくても X Window が表示できるようになった。

```bash
export DISPLAY=$(ifconfig | grep inet | awk '{if (NR==3) print $0}' | awk '{print $2}'):0
```

## 参考
- [WSL2におけるVcXsrvの設定](https://qiita.com/ryoi084/items/0dff11134592d0bb895c)
- [WSL2のGUI設定でつまずいたところ](https://qiita.com/baibai25/items/5841b0592727893d960f)
Amazon Forecast now supports accuracy measurements for individual items　翻訳まとめ

##はじめに
今回は、2020年11月24日に Namita Das 氏、Christy Bergman 氏、Punit Jain 氏によって投稿された 「Amazon Forecast now supports accuracy measurements for individual items」の記事を翻訳し、まとめました。
本記事のリンクは下記 URL 参照

■リンク
[Amazon Forecast now supports accuracy measurements for individual items](https://aws.amazon.com/jp/blogs/machine-learning/amazon-forecast-now-supports-accuracy-measurements-for-individual-items/)


## Amazon Forecast の新機能
この度、Amazon Forecast で個々のアイテムの予測精度を測ることができるようになりました。
これにより、特定のアイテムの予測精度を確認することが可能となります。


###各アイテムのバックテストと精度メトリクスから予測のエクスポート
この新機能を使う手順は以下です。


①Forecast のコンソール画面でデータセットグループを作成(今回は retail を選択)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/321349/dc1bb1d0-70dc-fe1d-f023-8d52fd422539.png)

②Target time series data のファイルをアップロード

③アップロード完了後、ダッシュボードの「Predictors」を選択し、「Train Predictor」をクリック

④予測トレーニングの入力項目に、以下の内容をそれぞれ入力
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/321349/73517832-aa3f-2d73-044e-17894314b148.png)


 - 「forecast horizon」 で「24」を選択
 - 「forecast frequency」で「hour」を選択
 - 「Number of backtest windows」で「5」を選択
 - 「Backtest window offset」で「24」を選択
 - 「Forecast type」の3つある入力箇所に「mean」、「0.65」、「0.90」とそれぞれ入力
 - 「Algorithm」で「Automatic」を選択

⑤予測のトレーニングが完了したら、「Predictors」ページでトレーニングが完了した予測子モデルを選択


⑥予測子モデルの詳細ページで「Predictor Metrics」にある「Export backtest results」を選択

⑦S3 に予測子モデルの csv ファイルをエクスポート

⑧S3 を確認すると、2つのフォルダにそれぞれ異なるファイルがあるのでそれを確認

 - forecasted-values：各バックテストウィンドウからの予測を含んでいます
 - accuracy-metrics-values：各バックテストウィンドウごとの各アイテムの精度メトリクスを含んでいます

accuracy-metrics-values のファイルには、wQL、WAPE、RMSE のメトリクスが提供されています。ファイルは出力されたデータの量に応じてファイルが複数ある場合があります。

■forecasted-values の csv データ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/321349/70c2e7a4-789a-d2ef-a47d-11275b73887a.png)


■accuracy-metrics-values の csv データ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/321349/54896f5b-3216-220d-2dd2-fc28d0ea896b.png)


9. ダッシュボードの「Forecasts」を選択し、「Create a forecast」を選択
10. 予測を実施する予測子モデルを選択

###バックテスト予測とアイテム精度のメトリクスの可視化
バックテストの可視化を実施する場合は、 QuickSight を利用する必要があります。
QuickSIght を利用することでグラフの可視化が可能となり、精度の正確性がより視覚的にも分かりやすくなります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/321349/56b56fac-57f1-d59c-5385-d2d67f2fd242.png)


##おわりに
翻訳まとめは以上となります。
バックテストが可能となったことと、個々の予測の精度を見ることができるようになったため今まで以上に使いやすくなったかと思います。
古典的な手法でAutonomous Database の スケジュールドスケールアップを行う

## はじめに
最近、耳にするようになったOracle Cloud Infrastructure（以下、OCI）ですが、2017年の誕生からあっという間に世界各国にリージョンが拡がっているようです。今回の記事のAutonomous Database（以下、ADB） も、2018年の誕生からどれくらいの稼働数になっているのか、その数に興味深々です。

さて今回は、とある統合DB環境でこのADBの無停止オートスケールアップが活躍している内容を書きます。

## どんなシステム？
こんな構成のシステムです。SNSへの一斉配信で、一瞬で反響がくるシステムです。

![sample1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/166030/301682f7-4b8e-5807-f5ec-f8104a239603.png)



## なぜ、ADB？
一言で言うと私が楽になりたいからです。

- DBサーバのスケールアップ・ダウンの作業を深夜に実施したくない。（一般的なDBだと、停止が必要だから）
- セキュリティパッチ適用のために週末をつぶしたくない。（パッチリリースが多い）
- DBチューニングの時間を短縮したい。（ある程度は自動チューニング機能に任せたい）
- ハードウェア障害での影響を最小化したい。（HA構成では不十分だから）
- Standard Edition Twoでは利用できない便利なEnterprise Edition機能を、気にせず使いたい。
- Oracleライセンス管理の手間を軽減したい。


## 本題のADBのスケジュールドスケールアップ
もちろん、Oracle EventsやOracle MonitoringやOracle Functionsを使って、今風に組むことはできそうですが、古典的な方法が一番、短時間でできたので、その方法を書きます。

oci cli環境のセットアップは、別のQiita記事や他ブログにもありますので、完了している前提です。
また、通常時は所有ライセンス数の制限により、Autoscaling=OFF, CPU数=3core, ライセンスモデル=BYOL で動いています。SNS配信直前に拡張をして、落ち着いた頃に元に戻します。

```ruby:ライセンスモデルをBYOLから、ライセンス込みへ変更
$HOME/bin/oci db autonomous-database update --autonomous-database-id ocid1... --license-model LICENSE_INCLUDED  --wait-for-state AVAILABLE
```

```ruby:CPU数を10に拡張（20vcpu相当）
$HOME/bin/oci db autonomous-database update --autonomous-database-id ocid1... --cpu-core-count 10 --wait-for-state AVAILABLE
```

```ruby:オートスケーリングを有効化（10core～30coreの範囲で負荷に応じて無停止＆高速スケールアップ可能な状態に）
$HOME/bin/oci db autonomous-database update --autonomous-database-id ocid1... --is-auto-scaling-enabled true --wait-for-state AVAILABLE
```


このままのサイズ(10core)で動かし続けると、ランニングコストが半端なく増加するので、元に戻す方法も記載します。

```ruby:オートスケーリングを無効化
$HOME/bin/oci db autonomous-database update --autonomous-database-id ocid1... --is-auto-scaling-enabled false --wait-for-state AVAILABLE
```

```ruby:CPU数を3にスケールダウン
$HOME/bin/oci db autonomous-database update --autonomous-database-id ocid1... --cpu-core-count 3 --wait-for-state AVAILABLE
```

```ruby:ライセンスモデルをライセンス込みからBYOLへ変更
$HOME/bin/oci db autonomous-database update --autonomous-database-id ocid1... --license-model BRING_YOUR_OWN_LICENSE --wait-for-state AVAILABLE
```

あとは、上記をそれぞれスクリプトにして、古典的な方法ですがcrondで実行します。SNS配信内容によりCPU拡張値が変わるため、引数として渡す構成にしています。

```ruby:/var/spool/cron/oracle
30 18 01 12 * $HOME/script/IncLic_Up_ASon.bash 10 >> $HOME/clilog/scaleup.log 2>&1
30 01 02 12 * $HOME/script/BYOL_Down_ASoff.bash 3 >> $HOME/clilog/scaledown.log 2>&1
```

一応、ちゃんと処理が完了したかは、slackに通知するようにして、最低限の確認は実施するようにしています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/166030/1c99f7c5-5411-d7f0-5069-9cae56d74a2f.png)

## あとがき
なぜ、私がADBやOCIをオススメしているのかを書きます。

それは、ADBを含め、沢山のサービスをAlways Freeで無料で使えるからです。Oracle DBの学習用でも、検証用途でも、個人の趣味サイトでも使えるからです。（Autoscalingは無料では使えませんが）

https://docs.oracle.com/ja-jp/iaas/Content/FreeTier/resourceref.htm

ぜひ、Always Freeも試してみてください！
Human In The Loop実装してみた  ― Part② 検証ツール ―


[Human In The Loop実装してみた ― Part① ダッシュボード ―](https://qiita.com/motonobu_ut/items/f05021b9e885d3770724)
の続きです。

Part①では、目標設定、使用データ紹介、モニタリング用ダッシュボードの実装を行いました。前提条件や目標、利用技術などの詳細は前回の[Part①](https://qiita.com/motonobu_ut/items/f05021b9e885d3770724)をご確認下さい。

＜HITL実装目次＞
Part①　ダッシュボード　←　前回
Part②　検証ツール　←　今回
Part③　HITL（①と②＋モデル再学習の仕組み）

■ ダッシュボード実装結果（前回）
![simpledashboard](https://user-images.githubusercontent.com/17790965/100710072-7ef4b280-33f2-11eb-846c-a2bfbc50a21e.gif)
■ 検証ツール実装結果（今回）
![simple_dashboard_fast](https://user-images.githubusercontent.com/17790965/100710944-dcd5ca00-33f3-11eb-938e-ad4e8c29562b.gif)

## Part②で何をやるか
Part①ではモニタリングで使用することを想定したダッシュボードを実装しました。
今回はモニタリングで不自然な振る舞いを発見した際、それが異常かを有識者が判定する作業を効率化するための検証ツールを実装します（以下「イメージ」の有識者判定部分）。

本記事の検証ツールは、アノテーションツールをベースとします。実装に入る前に、アノテーションについて簡単に説明し、どういうものを作ろうとしているかを整理します。
![HITL_5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/892617/ed81dbaa-d074-710b-5076-76327d9fded1.png)

## アノテーションとは
アノテーションとは、「特定のデータに対して情報タグ（メタデータ）を付加する」[参考1] ことを意味します。
本来、画像や自然言語など非構造化データにラベルを付与し、教師データとして学習を方向付けたり、効率化したりすることが多いのですが、今回はテーブルデータという構造化データに対して、モデルの再学習用に異常か正常かのラベルを付与することを考えます。
ちなみに、大量のアノテーションは手間のかかる作業であることが多く、外注するのにもコストがかかるため、限られた有識者のリソースを効率的に活かすためにも、今回のような検証ツールは必要だと考えます。
## 実装
以下に分けて実装していきます。
１．	ダッシュボード
２．	検証ツール　←　今回
３．	HITL（①と②＋モデル再学習の仕組み）

## ２．	検証ツール
■	実装内容

- 目標：構造化データにラベルを付与するツール
- 入力：テーブルデータ（csvファイル）
- 出力：入力＋検証結果
- ファイルの入力方法：選択とdrag & dropどちらも
- 基本機能：読み取り、表示、更新、削除
- オプション：初期化、sort、filter、export

■	実装イメージ　※IDは本件では時間(Time)
![HITL_4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/892617/8b96df94-db2b-7443-b3a7-ba1d45929476.png)
■	実装結果
![simple_dashboard_slow](https://user-images.githubusercontent.com/17790965/100711165-3d650700-33f4-11eb-816b-83b70e644e07.gif)

## Dashを使用した感想
このシリーズにおけるHuman In The Loop実装に必要なウェブアプリの実装箇所は今回で全てなので、メインで使用したDashというフレームワーク[参考4]について感想を述べたいと思います。
###Dashを使ってみた感想

- flaskをベースとしているだけあって軽量
- 簡易的なツール作成用という印象
    - 特にcallback関数がIDと一対一でないとエラーがでるなどは課題有
    - デフォルトだと自動コールバックがかかるので注意
- DataTableなど、不適切な引数を入れてしまうと表示されないものがあるので注意
    - DataTable表示のための関数はdashチュートリアルのものをコピーが簡単
    - （csvとxlsファイルをutf-8にデコードしてpandas DataFrameにしてくれる）
- bootstrapでレイアウトを決めても適切にstyle指定をしないと、はみ出したり背景色がおかしくなったりする

## まとめ
今回はHuman In The Loopにおける有識者検証時に使用する、検証ツールを実装しました。
検証ツールによって、検証対象データの取得、表示、確認、結果出力の流れがスムーズになり、手作業に比べ作業が効率化することが分かりました。また、今回はテーブルデータを表示しましたが、表示するものを文章にしたり画像にしたりすることで、典型的なアノテーションツールとしても利用できると感じました。
次回は今まで作成したダッシュボードと検証ツールに、モデルを再学習する仕組みを追加することで、Human In The Loopを実演したいと思います。

改善点やご質問などあれば、コメントいただければ幸いです。

## 参考
1.	アノテーションという言葉の意味
https://www.weblio.jp/content/アノテーション
（参考）アノテーションの種類：https://japan.zdnet.com/article/35134024/

2.	Dashで機械学習ができるWebアプリを作る [Step1]
https://wimper-1996.hatenablog.com/entry/2019/10/28/dash_machine_learning1
※	Dashのテーブルデータ処理などで参考にさせていただきました

3.	コード公開済み
http://github.com/utmoto

4.	Dash
https://dash.plotly.com/
5.	plotly
https://plotly.com/
VSCode : Remote Containers の備忘録

# はじめに

Remote Containersでいい感じに構築できたので、備忘録です。
(そのうちまとめたいな・・・と思いつつ)

# Remote Containersは遅いかも?

create-react-appで作成したものにDockerFileをそのまま追加して、Remote Containersで起動しました。
動きがローカルと比べると激遅です!!

# ~~改善~~ 改造

## 遅延の原因
Remote Containersで作成されたspaceでnpm startするとすごく遅くなりました。
ほかのspace(directory)でnpm startするとローカルと同じくらいの速度でした。

## 方針

1. 別のspaceで実施する
2. rsyncで能動的に同期する
3. 起動時に同期する

## コード
以下のように追加しました。

```:Dockerfile
FROM node:latest
WORKDIR /usr/app

RUN npm install -g create-react-app
RUN apt-get update -y && apt-get install -y rsync

# ライブ編集を有効か
ENV CHOKIDAR_USEPOLLING=true

# /usr/app に作業ファイルをcopyする
COPY . .
```

```:.devcontainer
...
	"postCreateCommand": "npm install",
	"postStartCommand": "rsync -ahv --stats --delete --exclude /node_modules --exclude /build --size-only ${DEV_CONTAINER} /usr/app/",
	"workspaceFolder": "/usr/app",
	"remoteEnv": {"DEV_CONTAINER": "/workspaces/${localWorkspaceFolderBasename}/" },
...
```

```:package.json
...
 "scripts": {
    "start": "node scripts/start.js",
    "build": "node scripts/build.js",
    "test": "node scripts/test.js",
    "local": "rsync -ahv --stats --delete /usr/app/ ${DEV_CONTAINER} --exclude /node_modules --exclude /build --size-only"
  },
...
```

## 注意点

Remote Containers上では、必ずnpm run localを行ってから閉じましょう・・・
でないと変更が消えてしまいます
【MongoDB】 "Unhandled rejection MongoError: (Unauthorized) not authorized..."の対処法

Mongooseを使っているときによくあるエラーかと思ったので共有します。

`Unhandled rejection MongoError: (Unauthorized) not authorized on admin to execute command { listIndexes: "sessions", cursor: {  } }`

こちらのエラーに関してです。

僕の場合、この原因はExpressのセッション処理が原因でした。
以下の部分です。

```javascript:server.js
app.use(session({
  resave: true,
  saveUninitialized: true,
  secret: 'aaabbbccc',
  store: new MongoStore({
    url: MONGO_URI,
    autoReconnect: true
  })
}));
```

こちらを以下のように書き換えます。

```javascript:server.js
app.use(session({
  resave: true,
  saveUninitialized: true,
  secret: 'aaabbbccc',
  store: new MongoStore({
    mongooseConnection: mongoose.connection,
    autoReconnect: true
  })
}));
```

これで解決しました。
【JS】関数を代入した変数を複数記述するときの注意点

Booleanを返す関数を代入した変数の処理で、**複数の条件（`&&`や`||`）を設定する場合**の記述の注意点メモ。

<br>
##正しい記述

複数の真偽値を設定する場合は、以下のように、**引数を明示して双方の変数にそれぞれ渡す**必要がある。

```js:OK事例
moreThanOne = ({arr}) => arr.length > 1
lessThanThree = ({arr}) => arr.length < 3

//正常な記述
judgeOK = (params) => lessThanThree(params) && moreThanOne(params)
```

<br>
これを、引数を記述せず、変数をつなげると意図しない結果になってしまう。

```js:NG事例
//間違った記述
judgeNG = lessThanThree && moreThanOne
```


<br>
##なぜ意図しない結果になってしまうのか？

```js:NG事例
judgeNG = lessThanThree && moreThanOne
```

この式は、lessTanThreeの結果と、moreThanOneの結果を&&で結んでいるのではなく、 **変数自体をつなげている**事になる。

&&は**前者がtrue / false以外の場合、後方の値を返す**。

このため、上記式は`judgeNG = moreThanOne`と同じになってしまう。


<br>
**▼true/false以外の場合の例**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/4298f79e-c104-3a0e-bebf-079f17b45e2e.png)


###▼確認用コード

```js:
arr = [1,2,3,4,5]

moreThanOne = ({arr}) => arr.length > 1
lessThanThree = ({arr}) => arr.length < 3

//意図しない動き
judgeNG = lessThanThree && moreThanOne
console.log( judge({arr}) ) //true

//意図した動き
judgeOK = (params) => lessThanThree(params) && moreThanOne(params)
console.log( judge({arr}) ) //false
```

上記のように、引数を記述しない場合は、後方のmoreThanOneのみが評価され、lessThanThreeが無視された結果になってしまう。

一方で引数を記述した場合は、`true && false = false`が返る。 


<br>
##paramsとは何か？

paramsは渡された引数全てを表している。引数名は任意なので、params以外でも問題ない。


```js:
arr = [1,2,3,4,5]

moreThanOne = ({arr}) => arr.length > 1
lessThanThree = ({arr}) => arr.length < 3

judge = (o) => lessThanThree(o) && moreThanOne(o)

console.log( judge({arr}) )
//false
```

上記の場合、`o`には`{arr}`が入っている。



<br>

##変数が一つの場合
変数が１つの場合引数を渡さずとも意図した動きになるため、これが混乱する要因にもなっていた、、

```js:
moreThanOne = ({arr}) => arr.length > 1

//意図した動きになる
judge = moreThanOne
judge({arr})
```

これは、judgeがmorethanOneに格納された変数そのものになっているため、引数を渡さずとも真偽値が返る。

`judge = moreThanOne`
　　　　　↓↑
`judge = ({arr}) => arr.length > 1`
.vscodeディレクトリは何の役割があるの？

# はじめに
![スクリーンショット 2020-12-01 16.30.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167220/7e94c7b8-3788-59ab-b834-23dbb960145f.png)
プロジェクトによってあったりなかったりする **「.vscode」フォルダ。。。**

なぜプロジェクトAでは存在するのにプロジェクトBでは存在しない？と思ったので、調べて検証してみました！

# Workspaceから設定ファイルを開いたら作成された！！！
![スクリーンショット 2020-12-01 16.29.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167220/0b48bac6-c6d5-9dc0-02b3-89b0521084df.png)
`Preferences＞Settings＞Workspace`から設定ファイル（右上のファイルアイコン）を開くと、作成されてた！！

で、**肝心のUserとWorkspaceの違いは何？という話**

# Workspaceの設定について
>Settingsには「User Settings」と「Workspace Settings」の2つがあります。
Workspace Settingsは個別のワークスペースやプロジェクトごとの設定を行うもので、User Settingsよりもこちらが優先されます。
https://blanche-toile.com/web/settings-visual-studio-code

ふむふむ。
・プロジェクトごとの設定がWorkspace
・VSCodeそのものの設定がUser

こんな感じかな？

プロジェクトごとに設定を変えたいならWorkspaceのSettingsを編集しましょう。

「WorkspaceのSettings」とは、つまり`myProject/.vscode/settings.json`と言うことである！！:relieved:

いやー、スッキリした
【Java】サーブレット(サーバサイドで動くJavaプログラム)


#  サーブレット

「WEBアプリを開発するために作られたプログラムの部品」

## 【説明】
<!-- サーブレットとは -->
サーブレットは、「**Webサーバー（HTTPサーバー）上で、ウェブページなどを動的に生成したり、データ処理を行うためにサーバサイドのプログラム** 」で、WEBアプリの中心を担う機能をもっています。

## 【メリット】

サーブレットはWEBアプリを開発する上で便利な特徴を持っています。

### データを再利用(ライフサイクルの管理)
処理が始まってから終了するまでの一連の流れを管理する機能をもっていて、効率よく仕事をするようにできています。
通常は、一連の処理が完了したらそれまでに使ったデータを破棄してしまいますが、サーブレットは一連の処理が終わっても、データを保持して再利用できるようにします。
そのため、最初の1回目は処理に時間がかかるものの、それ以降データを再利用するので処理が早くなります。
WEBアプリのような頻繁に不特定多数の処理を行う場合は、データをできる限り共有して使いまわした方が効率が良くなります。

### マルチスレッドに対応(同時に複数の処理をする)
1つのプログラムを実行している間は、他のプログラムは実行中のプログラムが処理されるのを待つ必要があり、WEBアプリでは、複数のユーザーから頻繁に同時にアクセスがあるため、常に順番待ちになってしまい効率が悪くなってしまいます。
サーブレットは複数の処理を同時に行う「マルチスレッド」に対応しているので、複数のユーザーからのアクセスでも効率良く処理を行うことができます。

### プラットフォームに依存しない
サーブレットはJavaのプログラムから作られていて、Windows, Mac, LINUXなどどの環境でも動作することが可能です。

<!-- 特徴「特筆すべき所」 -->
## 【特徴】
今までのJavaと大きな相違点は、「**Javaのプログラムが、ブラウザ上(HTTPサーバ上)で動くこと**」です。つまり、サーブレットはWebサーバ（HTTPサーバ）がなければ意味がありません。


<!-- 使用場面 「いつつかうか？」「どこで、つかうか？」-->
## 【使用場面】

サーブレットは「WEBブラウザからの要求に応えたり、送られてきたデータを処理したりする役割」で「WEBページをはじめとし画面に関する処理」は行いません。その特性から他のプログラムと連携することで真価を発揮します。

### JSP (HTML内にJavaのコードを埋め込む)
JSPは「動的にWEBページを生成する技術」でHTML内にJavaのコードを埋め込むことができます。

- サーブレットはWEBアプリ内部の処理
- JSPは主に外部の表示担当

と考えると良いかと思います。サーブレットとJSPが連携することで、

- 「特定のユーザー情報を画面に表示」する
- 「ログイン時に表示する画面の内容を変える」

といったような、いわゆる「動的なWEBページ」を作ることが可能です。

### Tomcat (サーブレットを動かすソフト)
サーブレット単独ではプログラムを動作させることができません。
Tomcatはサーブレットを動かすエンジンの役割をしていて、必要に応じて命令を出してサーブレットを動かしてくれます。

<!-- どの場面で使うのか記述 -->

<!-- ここから 各キャプチャー↓↓↓↓↓↓↓↓↓↓↓↓↓↓ -->
<!-- サンプルコード、サブセクションを記述↓↓↓↓↓ -->




<!-- サンプルコードや、サブセクションを記述↑↑↑↑↑ -->
<!-- ここまで 各キャプチャー↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑ -->


## 【まとめ】

JSP とサーブレットの関係についてようやく考えがまとまってきました。
近いうちになにかアプリを作ってみたいです。

## 参考文献・記事

- [Java Servlet（サーブレット）とは？超初心者向けに優しく解説](https://www.sejuku.net/blog/10496)

<!-- 以下リンク -->
[PHP]require_once

#PHPの require_once について
require_once(リクワイア ワンス)は、プログラムファイルを読み込む命令。読み込んだファイルをコードとして実行する。ワンスと付いているので、一度だけ読み込む。

読み込むファイルの拡張子は、何でもいいが、今回はPHPのコードを含んだファイルを読み込むので、phpという拡張子にしている

```java:HTMLテンプレート
<!DOCTYPE html>
<html lang='ja'>
    <head>
        <meta charset='utf-8'>
        <title>PHP-Web - wawawa</title>
        <style>body {padding: 10px;}</style>
    </head>
    <body>
        <h1>Hello templates</h1>
    </body>
</html>
```

```java:index.php
<?php
  // ここにテンプレートを読み込む
require_once'views/content.tpl.php';
```
```java:結果
> Hello templates
```
#以上！
SPSS Modelerによる製造系データの分析ハンズオン・コンテンツへのリンク

製造系のデータの分析でSPSS Modelerを活用する場合のハンズオン・コンテンツをまとめました。
どれもサンプルストリームとデータが用意されているので、SPSS Modelerをお持ちであれば実行して確認することが可能なコンテンツです。

# １．初心者向け
SPSS Modelerを使ったモデリングで故障予知や異常検知を行うイメージをつかむコンテンツです。

|コンテンツ|説明|
|---|---|
|[故障予知](https://qiita.com/kawada2017/items/0b04d5116bcc4b6ea9f6)|教師ありの故障予知のモデルを作成します|
|[異常検知](https://qiita.com/kawada2017/items/7e5a6ae61053093da89f)|教師データなしの異常検知のモデルを作成します|
|[装置故障分析](https://qiita.com/spssfun2017/items/d6b3dfd9cd5d1e0345a9)|教師ありの故障予知のモデルを作成します。予測だけではなく原因分析も行っています|

# ２．時系列のセンサーデータをつかったもの
時系列のセンサーデータはそのままではモデリングには使いにくいデータです。時系列の前後のデータをつかって特徴量を作成することに重点を置いたコンテンツです。

|コンテンツ|説明|
|---|---|
|[SPSS Modelerで時系列データをつかった故障分析①パターンの分類 ](https://qiita.com/kawada2017/items/7b4d29fe4a48a4afd779)|未加工の時系列のデータから故障分析。試行錯誤をしながらデータ探索しています|
|[SPSS Modelerで時系列データをつかった故障分析②故障予知](https://qiita.com/kawada2017/items/a7fa843e166dfa98ec73)|未加工の時系列のデータから故障分析。時系列データを加工しながら、故障予知をします|
|[時系列センサーデータからの特徴量抽出](https://qiita.com/kawada2017/items/49b93eccf7ae3d5ebfb6)|センサーデータを使った、差分や累積和、複雑な状態判定などの加工を行います。|
|[信号包絡線処理](https://qiita.com/kawada2017/items/f14b00974c4432d2a548)|センサーデータから信号包絡線を計算します。|
|[ブログで学ぶSPSS_Modeler #10- 異常検知の自動化！CADSの設定を動画でご紹介](https://www.ibm.com/blogs/solutions/jp-ja/learn-modeler-10/)|センサーの時系列の変化から異常を検知する内容です。さらにCADSと連携し自動的に検知するところまでを含んでいます|

#３．製品スペックからの分析
時系列データではないスペックデータを使った分析例のコンテンツです。

|コンテンツ|説明|
|---|---|
|[燃費分析](https://qiita.com/kawada2017/private/293faad1b5726bf5c6d1)|回帰分析やデータの可視化などを行います|
|[自動車スペックのクラスタリング](https://qiita.com/kawada2017/private/b56a538db697d31c4772)|kmeansをつかってクラスタリングを行います|

#４．故障実績データから故障予測（寿命予測）
|コンテンツ|説明|
|---|---|
|[故障予測・寿命予測](https://qiita.com/kawada2017/private/293faad1b5726bf5c6d1)|故障までの日数の実績からワイブル分析を使って故障予測を行います|
capistranoでデプロイするときにgitのエラー

よくあるデプロイコマンド
`$ cap staging deploy`
でエラー、あまり良く見たこと無いメッセージ、しかもついこの間までデプロイできてたのに…

``` bash
00:07 git:update
      01 git remote set-url origin git@bitbucket.org:hogehoge/hoge.git
    ✔ 01 hoge@foo.com 0.008s
      02 git remote update --prune
      02 Fetching origin
      02 error: rev-list died of signal 11
      02 error: rev-list died of signal 11
      02 error: bitbucket.org:hogehoge/hoge.git did not send all necessary objects
      02
      02 error: Could not fetch origin
```

なんじゃこりゃ。エラーメッセージでいろいろググってもあまりこれ！って解決方法は出てこない。

・リモートでgitを再インストール
・gemを全部アップデート

で解決した。アップデートで解決するやつってエラーわかりにくいわ…
AWSを勉強する - RDS

#RDS（Relational Database Service）
AWSが提供するマネージドRDBサービス。
MySQL、MariaDB、PostgreSQL、Oracle、Microsoft SQL Serverなどから選択できる。
Amazon Auroraは、AWSが独自に開発した、クラウドのメリットを最大限に生かした新しいアーキテクチャのRDS。

RDSは、複数のデータベースエンジンを利用できるが、それぞれのエンジンで提供されている機能のうち、RDSでは使用できない機能もあるので、機能制限をよく確かめる必要がある。
RDSで使えない機能が必要な場合は、EC2インスタンスにデータベースエンジンをインストールして使うなどの検討が必要。

##RDSで使えるストレージタイプ
RDSのデータ保存用ストレージには、EBSを利用。
EBSの中でもRDSで利用可能なストレージタイプは、下記の３つ

- 汎用SSD
- プロビジョンドIOPS SSD
- マグネティック

マグネティックは、過去に作成したDBインスタンスの下位互換性維持のために利用可能。
新しいDBインスタンスを作成する時は、基本的にSSDを選択。
プロビジョンドIOPSは、高いIOPSが求められている場合や、データ容量と比較してI/Oが多い場合に利用。

ストレージの容量は、32TBまで拡張が可能。
拡張は、オンライン状態で実施可能だが、拡張中は、若干のパフォーマンス劣化が見られる。（利用頻度が比較的少ない時間帯に実施したほうがいい）

##RDSの特徴

RDSを利用することで、複雑になりがちなデータベースの運用を、シンプルかつ低コストに実現できる。運用の効率化を図れる。

###マルチAZ構成
1つのリージョン内の2つのAZにDBインスタンスをそれぞれ配置し、障害発生時やメンテナンス時のダウンタイムを短くすることで高可用性を実現するサービス。

注意点

- 書き込み速度が遅くなる：2つのAZ間でデータを同期するため、シングルAZ構成よりも書き込みやこっミットにかかる時間が長くなる。
- フェイルオーバーには60~120秒かかる

###リードレプリカ
通常のRDSとは別に、参照用のDBインスタンスを作成することができるサービス。
利用可能なデータベースエンジンは、Aurora、MySQL、MariaDB、PostgreSQLの４つ。

リードレプリカを作成することで、マスターDBの負荷を抑えたり、読み込みが多いアプリケーションに置いてDBリソースのスケールアウトを容易に実現することが可能。
マスターとリードレプリカのデータ同期は、非同期レプリケーション方式。（リードレプリカを参照するタイミングによっては、マスター側で更新された情報が必ずしも反映されていない可能性がある）

###バックアップ／リストア

####自動バックアップ
バックアップウィンドウと保持期間を指定することで、1日に1回自動的にバックアップ（DBスナップショット）を取得してくれるサービス。
バックアップの保持期間は最大35日。
バックアップからDBを復旧する場合は、取得したスナップショットを選択して新規RDSを作成する。
稼働中のRDSにバックアップのデータを戻すことはできない。

####手動スナップショット
任意のタイミングでRDBのバックアップ（DBスナップショット）を取得できるサービス。
手動スナップショットの取得数は、1リージョンあたり100個まで。

####データのリストア
RDSにデータをリストアする場合は、自動バックアップ及び手動で取得したスナップショットから新規のRDSを作成する。

####ポイントインタイムリカバリー
直近5分前から最大35日前までの任意のタイミングの状態のRDSを新規に作成することができるサービス。

##Amazon Aurora

Auroraでは、DBインスタンスを作成すると同時にDBクラスタが作成される。
DBクラスタは、1つ以上のDBインスタンスと、各DBインスタンスから参照するデータストレージで構成されている。
AuroraのデータストレージはSSDをベースとしたクラスタボリューム。
クラスタボリュームは、単一リージョン内の3つのAZにそれぞれ2つのデータコピーで構成され、各ストレージ間のデータは自動で気に動悸される。





#用語まとめ

###フェイルオーバー
現用系コンピュータサーバ／システム／ネットワークで異常事態が発生したとき、自動的に冗長な待機系コンピュータサーバ／システム／ネットワークに切り替える機能。

###スイッチオーバー
何らかの異常を察知して、人間が手動で切り替えを行うこと。

###レプリケーション
あるコンピュータやソフトウェアの管理するデータ集合の複製を別のコンピュータ上に作成し、通信ネットワークを介してリアルタイムに更新を反映させて常に内容を同期すること。