2017 02-14 キュー実装に見る排他処理
TRANSCRIPT
キュー実装に見る排他処理CodeIgniter Night 2
2017-02-14 @noldorinfo
自己紹介•竹腰彰成(たけこしあきしげ)• Twitter: @noldorinfo• http://blog.noldor.info/
2
今日のテーマ• CodeIgniter4でキュー実装中です•仕様変更や機能追加するならリリース前のいまのうち•レビュー的な意味でツッコミお願いします
3
キューとはQueue
4
キュー( Queue)•先入れ先出し : First In First Out: FIFO•対義語はスタック( Last In First Out)•ここテストに出ます(※基本情報技術者試験)
5
図はWikiPediaよりhttps://ja.wikipedia.org/wiki/FIFO
キューの利用用途•フレームワークの場合、メッセージキューイング用途に使う•例)•メール送信のリクエストをため込む• PDF生成を別スレッドに処理させる
•つまり相手の応答を待たずに次の処理に移るために使う•何か重い処理をしたいが、今すぐでなくてよい•一方でブラウザにはすぐに応答したい•キューに入れてしまおう
6
※パンクするのでメッセージを溜め込んではいけません
処理が異常終了してメッセージが消える
7
処理始めるのでキューからメッセージ消しますー
Fatal Error!
メッセージを残すと二重処理
8
処理始めます、終わるまでメッセージ消しませんー
別のスレッドが同じメッセージ取り出しちゃった!
重い、終わらない……
そこで排他処理
9
処理始めます、作業中のマーキングしますー
次のメッセージをやるねー
重い、終わらない……
こんなライブラリがほしい!
キュー実装が help wantedに
10
リクエストされているキューの種類• RabbitMQ•ググると利用事例が結構あるキューのミドルウェア
• Local File•ミドルウェアなしでも動かしたいらしい
• Local Database• Webサーバが複数でも RDBで実装できていればいいよね
• Redis、Memcached• Webサーバが複数でも KVSで実装できていればいいよね
11
RabbitMQでの排他処理• Message Acknowledgment (ACK)• RDBのトランザクションのようなもの•作業中はセッションつなげっぱなし、終わったら ACKを投げる• ACKが戻る前にセッションが切れたら異常終了とみなす•セッションにタイムアウトはないので重い処理もできる
12
メッセージ取得
終わったら知らせる
セッション持ったまま処理
RDBで RabbitMQのマネはできない• RDBならトランザクションでやれば楽だよね!異常時にはロールバックできるし!
⇒行ロック・テーブルロック持ちっぱなし問題発生
13
メッセージ取得
終わったら commit
セッション持ったまま処理
DBへの負荷が!
トランザクションを使わない排他処理• UPDATEして affected rows > 0ならロックできた、とみなす• SQLが 1行で済むのでアトミック性は確保できている
•異常終了は検知できないのでタイムアウト処理を作る必要あり
14
まだ確認できてないこと• Radis/Memcachedで同じようなことできるの?•長時間セッション張っていいの?• FIFOできるの?•ググると実装はあるらしい
•ローカルファイルで汎用実装だと flock()だよね……• flock()は信用ならんイメージがある• mkdir()による代替実装って今どきやるのか?
アドバイスください!
15
ご清聴ありがとうございました
16