Link
Embed
Share
Beginning
This slide
Copy link URL
Copy link URL
Copy iframe embed code
Copy iframe embed code
Copy javascript embed code
Copy javascript embed code
Share
Tweet
Share
Tweet
Slide 1
Slide 1 text
CodeCrafters にチャレンジして PHP で Redis を作ってみる 2023/03/24 @PHPerKaigi 2023 げんえい (@gennei)
Slide 2
Slide 2 text
こんなことで悩んでいたりしませんか? 🤔🤔🤔 2
Slide 3
Slide 3 text
悩み ● チュートリアルを終えたけど次なにをしたらいいかわからない ● WAFを使ってアプリは作れるけど0から作る自信がない ● PHP以外の言語を学んでみたいけどなにをしたらいいかわか らない ● 複雑なアプリケーションの裏側を知りたい 3
Slide 4
Slide 4 text
今日はそんな悩みを 解決できるかもしれない話をします 4
Slide 5
Slide 5 text
自己紹介 $profile = [ '名前' => 'げんえい', '所属' => 'カオナビ', 'ロール' => 'テックリード', '好き' => ['コーヒー', 'サンフレッチェ広島', '読書'], ]; 5
Slide 6
Slide 6 text
6
Slide 7
Slide 7 text
Code Crafters とは ● 複雑なソフトウェアを作る練習ができるサイト ● “車輪の再発明” を通してプログラミングを学べる 7
Slide 8
Slide 8 text
どんなものを作るのか ● Redis ● Docker ● Git ● SQLite ● grep ● etc… 8
Slide 9
Slide 9 text
9
Slide 10
Slide 10 text
CodeCrafters の学習サイクル 1. アカウント作成 2. 課題のリポジトリをClone 3. 課題に沿ってコードを書く 4. PUSH すると CI が動きパスすると次の課題に進む 10
Slide 11
Slide 11 text
PHP で Redis を作ってみました 11
Slide 12
Slide 12 text
Redis ● インメモリデータストア ● Key-Value でデータ取得、保存 ● 有効期限の設定ができる 12
Slide 13
Slide 13 text
RESPとは ● Redis Serialization Protocol の略 ● 特徴 ○ Simple to implement.(実装が簡単) ○ Fast to parse. (パースが速い) ○ Human readable. (人間が読むことができる) 13
Slide 14
Slide 14 text
*2\r\n$4\r\nECHO\r\n$3\r\nphp\r\n 14
Slide 15
Slide 15 text
RESPの読み方 先頭の記号はデータのフォーマットを表す 15 記号 意味 + Simple String (改行コード許容しない) - Error : Interger $ Bulk String (改行コード許容する。バイナリセーフ。) * Array
Slide 16
Slide 16 text
Simple String ● +PING\r\n ○ + から始まり \r\n で終わる 16
Slide 17
Slide 17 text
Error ● -Error message\r\n ○ - で始まり \r\n で終わる 17
Slide 18
Slide 18 text
Integer ● :1000\r\n ○ : で始まり \r\n で終わる 18
Slide 19
Slide 19 text
Bulk String ● $5\r\nhello\r\n ○ $ は Bulk String を表す ○ $ の次の数字は文字列の長さを表す 19
Slide 20
Slide 20 text
Array ● *2\r\n$4\r\nECHO\r\n$3\r\nphp\r\n ○ * は Array を表す ○ * の次の数字は配列のサイズ ○ $ の次の数字は文字列長 20
Slide 21
Slide 21 text
*2\r\n$4\r\nECHO\r\n$3\r\nphp\r\n 21 *2 = 配列のサイズが2 $4 = 4文字(ECHO) $3 = 3文字(php)
Slide 22
Slide 22 text
RESP完全に理解した 22
Slide 23
Slide 23 text
CodeCraftersチャレンジしてみる 23
Slide 24
Slide 24 text
7つのステップ 1. 6379 port で待受 2. ping を送ると pong が返ってくる 3. 複数回コマンド対応 4. 並列でクライアントからのリクエスト処理 5. ECHO コマンドの実装 6. SET, GETコマンドの実装 7. Expire の実装 24
Slide 25
Slide 25 text
7つのステップ 1. 6379 port で待受 2. ping を送ると pong が返ってくる 3. 複数回コマンド対応 4. 並列でクライアントからのリクエスト処理 5. ECHO コマンドの実装 6. SET, GETコマンドの実装 7. Expire の実装 25
Slide 26
Slide 26 text
1. 6379 port で待受 ● cloneしたらすでにコードが書かれているので詳しく知らなくても大丈 夫 ● 主に socket_xxx() 系の関数を利用します ○ socket_create() // ソケット作成 ○ socket_bind() // 作成したソケットをaddress、portにバインド ○ socket_listen() // 接続待ち ○ socket_accept() // ソケットへの接続許可 26
Slide 27
Slide 27 text
27
Slide 28
Slide 28 text
7つのステップ 1. 6379 port で待受 2. ping を送ると pong が返ってくる 3. 複数回コマンド対応 4. 並列でクライアントからのリクエスト処理 5. ECHO コマンドの実装 6. SET, GETコマンドの実装 7. Expire の実装 28
Slide 29
Slide 29 text
2. ping を送ると pong が返ってくる ● +ping\r\n がクライアントから送られてくる ● +pong\r\n をクライアントへ返せば終わり ● レスポンスを返すときは socket_write() を使う 29
Slide 30
Slide 30 text
30
Slide 31
Slide 31 text
7つのステップ 1. 6379 port で待受 2. ping を送ると pong が返ってくる 3. 複数回コマンド対応 4. 並列でクライアントからのリクエスト処理 5. ECHO コマンドの実装 6. SET, GETコマンドの実装 7. Expire の実装 31
Slide 32
Slide 32 text
3. 複数回コマンド対応 ● while で無限ループしてコマンドを待つ 32
Slide 33
Slide 33 text
33
Slide 34
Slide 34 text
7つのステップ 1. 6379 port で待受 2. ping を送ると pong が返ってくる 3. 複数回コマンド対応 4. 並列でクライアントからのリクエスト処理 5. ECHO コマンドの実装 6. SET, GETコマンドの実装 7. Expire の実装 34
Slide 35
Slide 35 text
4. 並列でクライアントからのリクエスト処理 35 ● どのクライアントからの通信かを判定してレスポンスを返す ○ JavaScript で作っているとなにもしなくていいぞ
Slide 36
Slide 36 text
36
Slide 37
Slide 37 text
37
Slide 38
Slide 38 text
7つのステップ 1. 6379 port で待受 2. ping を送ると pong が返ってくる 3. 複数回コマンド対応 4. 並列でクライアントからのリクエスト処理 5. ECHO コマンドの実装 6. SET, GETコマンドの実装 7. Expire の実装 38
Slide 39
Slide 39 text
5. ECHO コマンドの実装 ● RESP フォーマットをパースして文字列を取得 ● socket_write() で入力された文字列を返す 39
Slide 40
Slide 40 text
*2\r\n$4\r\nECHO\r\n$5\r\nworld\r\n 40 *2 = 配列のサイズが2 $4 = 4文字(ECHO) $5 = 5文字(world)
Slide 41
Slide 41 text
41
Slide 42
Slide 42 text
*2\r\n$4\r\nECHO\r\n$5\r\nworld\r\n 42 *2 = 配列のサイズが2 $4 = 4文字(ECHO) $5 = 5文字(world)
Slide 43
Slide 43 text
7つのステップ 1. 6379 port で待受 2. ping を送ると pong が返ってくる 3. 複数回コマンド対応 4. 並列でクライアントからのリクエスト処理 5. ECHO コマンドの実装 6. SET, GETコマンドの実装 7. Expire の実装 43
Slide 44
Slide 44 text
6. SET, GETコマンドの実装 ● PHPの1プロセスが起動している状態なのでストレージとなる シングルトンを作成し読み書きする 44
Slide 45
Slide 45 text
45
Slide 46
Slide 46 text
7つのステップ 1. 6379 port で待受 2. ping を送ると pong が返ってくる 3. 複数回コマンド対応 4. 並列でクライアントからのリクエスト処理 5. ECHO コマンドの実装 6. SET, GETコマンドの実装 7. Expire の実装 46
Slide 47
Slide 47 text
7. Expire の実装 ● Expire ○ SET KEY VALUE 単位 (時間) で指定する ○ 指定は ex(秒) または px(ミリ秒) で指定する ○ ex) SET lang php px 100 47
Slide 48
Slide 48 text
48
Slide 49
Slide 49 text
49
Slide 50
Slide 50 text
時間があればデモ 50
Slide 51
Slide 51 text
まとめ ● RedisはRESPがわかれば作れる! ● 順番に小さく作ることでコア機能は作れる ● 新しい言語を習得するときはCodeCraftersでやってみるのい いかもしれない 51
Slide 52
Slide 52 text
参考文献 ● Redis 公式ドキュメント ○ https://redis.io/docs/ ● 実践Redis入門 技術の仕組みから現場の活用まで ○ https://gihyo.jp/book/2022/978-4-297-13142-5 52
Slide 53
Slide 53 text
おわり 53
Slide 54
Slide 54 text
おまけ 54
Slide 55
Slide 55 text
RESP3 ● Redis6.0 以降ではRESP3を使うことができる ● 主な変更点 ○ CRLF -> LF に変更 ○ データ型の追加 ■ Map、Set、Boolean、etc.. 55