GNU版のコマンドセットをMacに入れておく
メモ
$ brew install coreutils $ brew install gnu-sed $ brew install gawk $ brew tap homebrew/dupes $ brew install homebrew/dupes/grep
Rubyで外からプライベート変数にアクセスする
# プライベート変数の定義状況を確認する obj.instance_variable_defined?('@raw') # プライベート変数にアクセス obj.instance_variable_get('@raw')
SJISのCSVからシェルで集計するまでの流れ
CSVのデータを集計を、シェルでさくっと終わらせたいときのためのメモです。
まずは文字コードを変換
だいたいCSVはSJISであることが多いので、シェルで正しく処理できるようにUTF-8に変換します。
# 使える文字コード一覧 iconv -l # f(from)の文字コード # t(to)の文字コード iconv -f SJIS -t UTF8 target.csv > _target.csv
tsvに変換する
CSVは扱いづらいのでタブ区切りに変換します。
# csv2tsv.rb require 'csv' fn = ARGV[0] if fn.nil? puts "CSVファイル名を指定してください" exit elsif File.extname(fn) != ".csv" puts "CSVファイルを指定してください" exit end fw = File.open("#{File.basename(fn, '.csv')}.tsv", 'w') CSV.foreach(fn, 'r') do |row| fw.puts(row.join("\t")) end fw.close puts 'created tsv_file'
実行
ruby csv2tsv.rb target.csv
awkで集計する
# 9列目が特定の値の行だけ出力 cat *.gz | gzip -dc | gawk '{if ($9 >= 500) print $0};' # 12列目をsumして出力 cat target.tsv | gawk -F"\t" '{s += $12} END {print s}' # 10列目でグルーピングして、12列目をsumして出力 cat target.tsv | gawk -F"\t" ' { count[$10]+=1 sum[$10]+=$12 }; END { for (key in sum) { print key, count[key], sum[key] } } '
Redisへの負荷を分散するためにtwemproxyを使ってシャーディングする
概要
Redis負荷分散のために前段にプロキシ(twemproxy)を配置/運用した内容について記載します。
twemproxyはコンシステントハッシュを使用してシャーディング(キーの分散)を実現します。
なお、twemproxy詳細については https://github.com/twitter/twemproxy を参照してください。
なぜ必要
"書き込みも含めた"Redisへの負荷を分散するため。
読み込みだけの負荷を分散するのであればリードレプリカがあれば大丈夫。
システム構成
Railsアプリ - NLB - ターゲットグループ(blue/green) - EC2(tewmproxy)×N台 - Redis×N台
※ターゲットグループ/EC2はblue系とgreen系を準備して、blue/greenデプロイが可能な構成としています。
構築方法
twemproxyをAmazonLinuxにインストールする
ansible-roleを作成したので、こちらを使ってください。
https://github.com/kinosuke01/ansible-twemproxy
twemproxyの設定概要(ansibleでの設定)
twemproxy_pools: redis: listen: 127.0.0.1:6379 # listenするアドレス:ポート hash: fnv1a_64 distribution: ketama auto_eject_hosts: "true" # redisが死んだときに切り離す(true)か否(false)か redis: "true" # バックエンドにredisを使う(falseだとmemcached使う) server_retry_timeout: 30000 # 下記「redisの切り離しについて」参照 server_failure_limit: 1 # 下記「redisの切り離しについて」参照 servers: # バックエンドのredisアドレスを配列で記載 - redis01.example.com:6379:1 - redis02.example.com:6379:1
ファイルディスクリプタの上限設定(ansibleでの設定)
ファイルディスクリプタのデフォルト上限1024では足りないほどに
twemproxyへの同時アクセス数がある場合は、ansibleで下記変数を設定します。
twemproxyの起動スクリプト内でこの数値で `ulmit -n value` されるようになります。
twemproxy_file_max: 500000
ヘルスチェックについて
twemproxyのmonitoring portである22222ポートを使用する。
運用について
Redisのつけ足しについて
バックエンドのredisを付け足ししたい場合も、blue/greenデプロイすることで無停止で付け足しが可能。
以下、手順を記載します。(前提としてblueがアクティブな状態とします。)
1) Redisを新たに構築。
2) 新たに構築したredisのエンドポイントをgreen系の設定ファイルに追加。twemproxyを再起動。
(ansibleでblue系とgreen系の設定を分けておくと安全)
3) nlbでターゲットグループをblueからgreenに切り替える
4) grenn系がhealthyになったことを確認したら、blue系のEC2にログインしてtwemproxyをstopもしくはrestartする。
(これをしないとblueにも通信が流れ続ける。TCPセッションが切れないため?詳細は不明)
Redisの切り離しについて
server_retry_timeout: 30000 とした場合、
1) キーにヒットするRedisが死んだ。
2) 30000msec以内に同じキーでアクセスする
3) リング状の次のRedisで read or writeが行われる。
4) 次のRedisが使われるようになってから30000msec経つと、またもともとのRedisを参照するようになる。(で死んでいたらまたリング状の次のRedisが使われる)
という動きになる。
Redisクライアント側の対応
・Redisのつけ足しについて/Redisの切り離しについての挙動があるため、ttl期限なしは設定しない。
Redis増やしたり切り離されたりしたときに、内容が古い消えていないキャッシュにヒットしてしまう可能性があるため。
・すべてのRedisコマンドが使えないので、クライアント側でそれらの使用を控えるか何らかの対策をする必要がある。
https://github.com/twitter/twemproxy/blob/master/notes/redis.md
大きな点でいうとkeys,flushdbが使えない。
keysが使えないのでキー部分一致による削除ができない。
zipコマンドメモ
# zip圧縮 zip -r filename.zip fileDir # zip圧縮(パスワード) zip -re filename.zip fileDir # zip解凍 unzip filename.zip
SublimeTextで設定したことメモ
随時追加
¥(円)マークで\バックスラッシュを入力
Sublime Text 2 -> Preferences -> Keybindings - User
でキーマップの設定画面を開き、下記の行を追加する。
{ "keys": ["\u00a5"], "command": "insert", "args": {"characters": "\\"}}
参考にさせていただきました。
Sublime Text2 ¥(円)マークで\バックスラッシュを入力 – 黒川仁の文具堂ブログ三昧