Skip to content

Instantly share code, notes, and snippets.

@takuma-saito
Last active March 3, 2016 08:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save takuma-saito/1b531593bfc99a245f91 to your computer and use it in GitHub Desktop.
Save takuma-saito/1b531593bfc99a245f91 to your computer and use it in GitHub Desktop.
並列化クローリングのメモ.txt
* GIL (Global Interepter Lock) が存在するために ruby, python ではマルチコアを生かせない(コア数に比例してクローリングの数が増えない)
⇒ 対策: マルチコアを生かすには GIL が存在しない java や C++ か、メッセージバッシングの行える Scala, Go, Closure を使う
⇒ 今回はあまり癖がなく Garbage Collector が付いている Go を選択する
### 20 (page/second) の壁
* ファイルディスクリプタの枯渇で死ぬ
⇒ 対策
* ulimit -u 40000
* /etc/security/limits.conf で
username soft nofile 40000
username hard nofile 40000
* スレッドの生成しすぎで死ぬ
⇒ 対策
* ulimit -n 40000
* /etc/security/limits.conf で
username soft nproc 40000
username hard nproc 40000
* Go の並列化が 1 url 1 goroutine だとあまり性能が出ない timeout で溢れる
⇒ groutine pool を作りそこに流し込む, producer も consumer も goroutine プールの数だけ生成する
* マルチコアの強力なCPUを持つ EC2 サーバーで実行する(c4.8xlarge)
ここまでで Macbook Pro (8GB Memory, Core i5) で事実上の上限値 100 (page/second) 出る
ネットワーク帯域がもっとあればさらに増やせるかもしれない
### 100 (page/second) の壁
* 今度は Name Resolver がボトルネックになる。DNS への応答が timeout で返って来ない
⇒ 名前解決するだけのスクリプトで並列化ベンチマークを取ったところ 300 (query/second) あたりが google public DNS の上限と判明
### 300 (page/second) の壁
- ローカルに再帰問い合わせ用のキャッシュサーバーを用意し、そこにリクエストを送るようにする
- 並列化の数を増やす(1000)
- ローカルポートの数を増やす
- tcp, udp バッファを増やす
### 1500 (page/second) の壁
- glibc を通さず DNS の UDP 問い合わせを非同期で行うようにする
- goroutine pool を増やしてパイプライン処理に分割する
### 5000 (page/second) の壁
- 複数サーバーでの分散処理を入れる
### 15000 (page/second) の壁
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment