ルックルックこんにちは(DNSの話だよ
前回までのあらすじ
ngx_mrubyからDynamoDBにアクセスするために、ちょっとしたクライアントを書いたYO
今回のお話
DynamoDBのエンドポイント、digるたびに違うIP返しますね?
正確には5秒毎に異なるIPが返ってくる
;; ANSWER SECTION: dynamodb.ap-northeast-1.amazonaws.com. 5 IN A 52.94.8.154
INの前にある5っていうのがTTL
キャッシュサーバから5秒毎にキャッシュが消えるので、違うIPが返ってくるという感じか
まあこの挙動自体はDNSラウンドロビン的なやつなので、特にいうことはない
微妙にping値が良いIPがありますぞ
ec2インスタンス内からping叩いて調べたところ、ほとんどは3ms程度で返ってくるんだけど、中には応答速度が1msを切るIPがあったりする。
なんでしょうね。。。?ec2インスタンスと物理的近い位置に存在するのかな?ていうか同一のAZに存在するエンドポイントの場合にpingの応答が早くなってるのかな?
このAZ間通信のレイテンシ問題、要求レスポンス速度がシビアな分野だと問題になるんですよね。
(まだAZが異なるのが原因とは断定できないが)
elasticacheへのアクセスとか、AZまたぐとレイテンシが大きくなるために、シングルAZに寄せて運用してたり。。。
じゃあ/etc/hostsにping値の良いIP書いちゃえばいいじゃん?
と思うじゃん?
当然アンチパターンとされてるわけです。
Q5: DynamoやAuroraを利用する際のアンチパターンは何か有りますか?
A5: アンチパターンとしましては、DNS名を使わないで、DynamoやAuroraのDNS名を名前解決してそのIPを利用されるパターンが考えられます。直接IPを指定するのではなく、DNS名を使うようにしましょう。また、アプリ側でDNSキャッシュをTTLを無視してしまう場合があります。使う場合には、IPアドレスが動的に変更されることがあり得ますので、DNSキャッシュのTTLを無視しないようにしましょう。JVMではDNSキャッシュしてしまうのがデフォルトでしたので注意しましょう。
あ、はい^^
ping値の良いIPを選択して少しでもネットワークレイテンシを軽減するっつーのはムリっぽいですねー。
あれ?TTLが短いということは、頻繁にDNSルックアップが走るということになります?
単純に考えると、5秒毎にDNSルックアップが走るのか〜?そんでIP変わるからKeepAliveも切れるのか〜???
という懸念点があったので、ちょいと調べた
そもそもHttpクライアントが内部にDNSキャッシュ持ってたりするよな
持ってたりします。
上記の引用にもあるんだけど、JavaはDNSレコードに設定されているTTLを考慮せずにキャッシュして、かつデフォルト設定だとキャッシュのTTLが無限なので、別途TTLを設定しないままAWSのマネージド・サービスのエンドポイントにアクセスすると、途中でつながらなくなったりするようだ。
DNS 名を参照するための JVM TTL の設定 — 開発者ガイド
今回作ったmrubyのDynamoDBクライアントはHttpクライアントとしてmruby-curlを使っているので、このあたりの事情はlibcurlに準拠する。
上記リンク先の公式ドキュメントによると、デフォルト60秒間キャッシュするらしい
ほんとはDNSレコードのTTLを尊重したほうがいいんだろうけど、とりあえず大丈夫だろう。
サーバ内にDNSキャッシュおけばええんちゃう
ってちょっと思ったけど、DNSキャッシュサーバはDNSレコードのTTLを考慮してキャッシュを消すはずなので、あんまり置く意味はないか。
今回のケースだとアプリ内部でもキャッシュしてるし。
環境はAWSなので、DNSサーバはvpc内のprivate DNSを見に行くんだけど、このへんで障害起こったことってあるんだろうか。
サーバ内でDNSキャッシュサーバ動かしたら一応可用性の向上にはなるのか
(DynamoDBについてはTTLが短いからあんまり意味ない気がするが)
結局問題は解決してない
DNSルックアップが走るのはしゃーないし、KeepAliveも切れますよと
でも、仮にIPがA〜Fとあるとして、DNSルックアップした際にそれらを順繰りに返してるとしたら、以前アクセスしたことのあるIPについてはKeepAliveが持続してたりする?
(このへんのレイヤー理解が乏しいんだよな。。。)
ちょっとでもDynamoDBのレイテンシを小さくしようとしたら、いまんとこDAXを使うのが確実なんだろうけど、クライアントがJava版しかないんだよね。
しかもHttpじゃなくてTCPで通信してるみたいだし
ソースはgithubで参照できるから、mrubyに移植するのも不可能ではないと思うんだけど、通信仕様をドキュメントとして公開してない(まだしてないよね?)ってことは、なんか破壊的変更が入る可能性も考えられるよなあ
というかDynamoDB、たまにスパイク発生するのが厳しいんですが。。。
主キーを使った単純なGETで、jmeterでしばいてみると、cloudwatchで平均3msちょいのレイテンシになるのだけど、最高値で50msとか出る。
ngx_mrubyだとデータストアへのアクセスでスパイク発生すると、そこで詰まるんですよね。
アドテクでDynamoDB使ってる事例、AWSのページに結構のってるけど、このあたりの問題どうやって攻略してるんだろう。