Search on the blog

2017年11月1日水曜日

L2接続とL3接続の違い

Ciscoのページがとても分かりやすかった。

違いを表にまとめておく。
レイヤー OSIモデル アドレス 通信単位 接続対象
L2 データリンク層 MACアドレス フレーム LAN内の端末
L3 ネットワーク層 IPアドレス パケット LAN同士

2017年10月30日月曜日

GCPとjavascriptでaccess trackerを作る(3)

backend(リクエストを受けてpub/subに流すコンポーネント)がほぼ出来上がった。

https://github.com/Kenji-H/access-tracker-backend/tree/v0.9.2

進捗
  • google container engineのクラスタを立てた
  • deploymentとserviceの定義を書いた
  • READMEを書いた
  • alpineで動かすとgcpのライブラリのロードでこけることがわかったのでfixした

動作確認
データを投げる。
$ cat test.json
{
  "userid": "610KZ4G0CBTI419Y",
  "timestamp": 1509290846000,
  "pageid": "test-page-001",
  "browser": "chrome",
  "country":"japan"
}
$ curl -H 'Content-Type:application/json' -d @test.json xxx.xxx.xxx.xxx/pv

アプリケーションのログを確認する。
$ kubectl --namespace=backend logs -f access-tracker-backend-xxxxxxxx
received request for URL: /pv
success: {"userid":"610KZ4G0CBTI419Y","timestamp":1509290846000,"pageid":"test-page-001","browser":"chrome","country":"japan"}

pub/subにデータが流れたことを確認する。
gcloud beta pubsub subscriptions pull test --auto-ack --max-messages 1000
│ {"userid":"610KZ4G0CBTI419Y","timestamp":1509290846000,"pageid":"test-page-001","browser":"chrome","country":"japan"} │ 165859404777865 │            │

次やること
  • droneサーバを立てる
  • unittestを書く
  • CI/CDの設定をする

2017年10月29日日曜日

GCPとjavascriptでaccess trackerを作る(2)

https://github.com/Kenji-H/access_tracker/tree/v0.9.1

今日の進捗
  • pub/subにデータをpublishする部分を実装した
  • データをvaldationする機能を実装した
  • expressに404と500のhandlerを追加した

新しく学んだこと
  • node.js向けのgcp client libraryは基本非同期処理で書くようになっているが、callbackを省略するとpromiseオブジェクトを返してくれる。
  • promiseオブジェクトをチェーンで繋げて書くとうまく書けそうだが、繋げたいメソッドの入出力がうまくハマらなかったり、細かい例外処理をしたかったりすると、自分でpromiseオブジェクトを作成した方が書きやすい感じがした。たぶん自分のnode.js力が低いだけで、慣れてきたらもっとうまく書けそう。
  • gcpのcredentials/projectidは環境変数に入れるとすっきりする。
  • jsonをバリデーションしたい場合は、jsonschemaというライブラリを使うといいらしい。
  • expressにはエラーハンドラを登録することができる。404のハンドラの定義はファイルの一番下部でやらないといけない。

次やること
  • gkeのクラスタを立てる
  • gkeでコンテナを動かす
  • プロジェクト構成を整理する(デプロイの単位は分けるつもりだったが、レポジトリ自体も分けた方がすっきりしそう)

2017年10月28日土曜日

GCPとjavascriptでaccess trackerを作る(1)

 最近GCPを使ったインフラ構築と、javascriptへの興味が高まっているので、勉強がてら何か作ってみることにした。

作りたいやつの機能
  • サーバサイドはnode.jsで書く。REST APIでページビュー情報をPOSTしたり、ページビュー情報をGETしたりできる。
  • POSTされた情報はGCPのpub/subにpublishされる。
  • GETするときはpub/subからsubscribeする。
  • サーバ自体はGCPのcontainer engineで動作する。
  • クライアントサイドはReact.jsで書く。
  • グラフライブラリを使ってかっこいいグラフを表示する。
  • Websocketを使ってリアルタイムにグラフが更新されるようにする。
今日の進捗
node.jsでサーバを書いて、Dockerで動くようにした。

https://github.com/Kenji-H/access_tracker/tree/v0.9.0

ローカルでの動作確認方法は以下のとおり。

まず、dockerを起動。
$ cd server
$ docker build -t test .  
$ docker run --rm -p 8080:8080 test

クライアントからリクエスト送信。
$ curl localhost:8080/status
$ curl -H 'Content-Type:application/json' -d '{"userid": "610KZ4G0CBTI419Y", "timestamp": 1509130332, "url": "kenjih.com", "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36"}' localhost:8080/pv

dockerにログが出ていることを確認。
received request for URL: /status
received request for URL: /pv
userid: 610KZ4G0CBTI419Y
timestamp: 1509130332
url: kenjih.com
userAgent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36

2017年10月21日土曜日

Signal Handler in Python

PythonでSignal Handlerを書いて遊んでみた。

プログラム
Python 3で動作確認してます。
遊び方
まず上記のPythonプログラムを起動します。
$ python sample.py

プログラムを起動したら以下の表を参考にシグナルを送ってみてください。
シグナル キーボードから コマンドラインから
SIGINT ctrl + c kill -INT プロセス番号
SIGTSTP ctrl + z kill -TSTP プロセス番号
SIGTERM - kill プロセス番号
SIGKILL - kill -KILL プロセス番号

プログラムを停止したい場合は、SIGKILLを送ってください。
プログラムのプロセス番号は以下のコマンドで調べることができます。
$ pgrep -f "python sample.py"

単一障害点とは

まえがき
システム全体のアーキテクチャを考えるときに、「単一障害点」という概念が大事らしい。
意味は一目瞭然だけど、大切な概念っぽいので調べてみることにした。

語句の意味
その単一箇所が働かないと、システム全体が障害となるような箇所のこと。
ちなみに英語だとSingle Point of Failure(SPOF)というらしい。

単一障害点の例
コンポーネント 説明
アプリケーションサーバ アプリケーションサーバが一つしかないと、クリティカルなエラーが発生したときにユーザがシステムを利用できなくなってしまう。よってサーバをレプリケーションしておくことでSPOFにならないようにする必要がある。
ディスクストレージ ディスクストレージが故障するとデータの読み書きができなくなり、システム全体が利用不可になってしまう可能性がある。よってRAIDなどの冗長構成を取る必要がある。
ネットワークスイッチ ネットワークスイッチが故障と、ネットワーク内のサーバ間の疎通ができなくなってしまう。よって冗長なスイッチとネットワーク構成によって、SPOFを解決する必要がある。

トレードオフ
SPOFを解決するためには、レプリケーションや冗長構成などが必要となるので、コストがかかる。
どこまでSPOFの排除に取り組むかはコストとのトレードオフも考えて決定しなければならない。

2017年10月1日日曜日

Perplexityとは

 自然言語処理で良く使われるメトリクスのひとつであるperplexityについて説明します。

定義

分布pに従って生成されるデータxがある。xの分布をqでモデリングする。
このとき確率モデルqのperplexityは、

と表される。
ただし、xiはpから生成したデータで、Nはxiの個数である。

直感的な説明

  • 指数部はクロスエントロピーになっている
  • モデルにデータを見せたときに、どれくらい"驚く"かを表す
  • いいモデルほどperplexityは小さい

サンプル

サイコロの目の分布をモデリングしてみて、そのモデルのperplexityを計算してみます。
まずサイコロを用意します。サイコロは六面で各面が出る確率は一様とします。

真の分布はわからないので、30回サイコロを振ってみて観測化された結果から分布を推定してみます。このモデルのperplexityをテストデータ1,000個を使って計算してみると、6.358となります。


import numpy as np
from collections import Counter

np.random.seed(1234)


N = 1000     # test data size
M = 30       # train data size

test_data = np.random.randint(6, size=N)
train_data = np.random.randint(6, size=M)

p = Counter(test_data)    # test distribution
q = Counter(train_data)   # proposed distribution

exponent = 0
for i in range(6):
  exponent -= p[i] / N * np.log2(q[i] / M)

print (2 ** exponent)

次に訓練データを増やしてモデリングしてみます。サイコロを1,000回振ってみます(上記のコードのMを1000に変更してプログラムを実行)。
perplexityは5.998となり、モデルの良さが改善されたことがわかります。