Upgrade to Pro — share decks privately, control downloads, hide ads and more …

CodeCrafters にチャレンジして PHP で Redis を作ってみる

gennei
March 24, 2023

CodeCrafters にチャレンジして PHP で Redis を作ってみる

みなさんは CodeCrafters というサイトを知っていますか?
このサイトは少し複雑なソフトウェアを作りながらプログラミングを学ぶことができるサイトです。
このサイトではRedisやDockerコマンド、SQLite などの基本的な機能を作るような練習問題があります

Redisを作る課題にチャレンジしました。そこで学んだことを話そうとおもいます。

■話すこと
・CodeCraftersってどんなサイトなのか
・CodeCrafters で Redis を作る手順について
・Redisのプロトコル(RESP)について

■ターゲット
・PHPの基本的な文法はわかるけど次に何をするか悩んでいる人
・PHP以外の言語でなにか作りたいけど作りたいものがない人

gennei

March 24, 2023
Tweet

More Decks by gennei

Other Decks in Programming

Transcript

  1. 自己紹介
 $profile = [
 '名前' => 'げんえい', 
 '所属' =>

    'カオナビ', 
 'ロール' => 'テックリード', 
 '好き' => ['コーヒー', 'サンフレッチェ広島', '読書'],
 ];
 5
  2. 6

  3. 9

  4. RESPとは
 • Redis Serialization Protocol の略
 • 特徴 
 ◦

    Simple to implement.(実装が簡単)
 ◦ Fast to parse. (パースが速い)
 ◦ Human readable. (人間が読むことができる)
 13
  5. RESPの読み方
 先頭の記号はデータのフォーマットを表す
 15 記号
 意味
 +
 Simple String (改行コード許容しない) 


    -
 Error
 :
 Interger
 $
 Bulk String (改行コード許容する。バイナリセーフ。) 
 *
 Array

  6. Bulk String
 • $5\r\nhello\r\n
 ◦ $ は Bulk String を表す


    ◦ $ の次の数字は文字列の長さを表す
 19
  7. Array
 • *2\r\n$4\r\nECHO\r\n$3\r\nphp\r\n
 ◦ * は Array を表す
 ◦ *

    の次の数字は配列のサイズ
 ◦ $ の次の数字は文字列長
 20
  8. 7つのステップ
 1. 6379 port で待受
 2. ping を送ると pong が返ってくる


    3. 複数回コマンド対応
 4. 並列でクライアントからのリクエスト処理
 5. ECHO コマンドの実装
 6. SET, GETコマンドの実装
 7. Expire の実装
 24
  9. 7つのステップ
 1. 6379 port で待受
 2. ping を送ると pong が返ってくる


    3. 複数回コマンド対応
 4. 並列でクライアントからのリクエスト処理
 5. ECHO コマンドの実装
 6. SET, GETコマンドの実装
 7. Expire の実装
 25
  10. 1. 6379 port で待受
 • cloneしたらすでにコードが書かれているので詳しく知らなくても大丈 夫
 • 主に socket_xxx()

    系の関数を利用します
 ◦ socket_create() // ソケット作成
 ◦ socket_bind() // 作成したソケットをaddress、portにバインド
 ◦ socket_listen() // 接続待ち
 ◦ socket_accept() // ソケットへの接続許可
 26
  11. 27

  12. 7つのステップ
 1. 6379 port で待受
 2. ping を送ると pong が返ってくる


    3. 複数回コマンド対応
 4. 並列でクライアントからのリクエスト処理
 5. ECHO コマンドの実装
 6. SET, GETコマンドの実装
 7. Expire の実装
 28
  13. 2. ping を送ると pong が返ってくる
 • +ping\r\n がクライアントから送られてくる
 • +pong\r\n

    をクライアントへ返せば終わり
 • レスポンスを返すときは socket_write() を使う
 29
  14. 30

  15. 7つのステップ
 1. 6379 port で待受
 2. ping を送ると pong が返ってくる


    3. 複数回コマンド対応
 4. 並列でクライアントからのリクエスト処理
 5. ECHO コマンドの実装
 6. SET, GETコマンドの実装
 7. Expire の実装
 31
  16. 33

  17. 7つのステップ
 1. 6379 port で待受
 2. ping を送ると pong が返ってくる


    3. 複数回コマンド対応
 4. 並列でクライアントからのリクエスト処理
 5. ECHO コマンドの実装
 6. SET, GETコマンドの実装
 7. Expire の実装
 34
  18. 36

  19. 37

  20. 7つのステップ
 1. 6379 port で待受
 2. ping を送ると pong が返ってくる


    3. 複数回コマンド対応
 4. 並列でクライアントからのリクエスト処理
 5. ECHO コマンドの実装
 6. SET, GETコマンドの実装
 7. Expire の実装
 38
  21. 41

  22. 7つのステップ
 1. 6379 port で待受
 2. ping を送ると pong が返ってくる


    3. 複数回コマンド対応
 4. 並列でクライアントからのリクエスト処理
 5. ECHO コマンドの実装
 6. SET, GETコマンドの実装
 7. Expire の実装
 43
  23. 45

  24. 7つのステップ
 1. 6379 port で待受
 2. ping を送ると pong が返ってくる


    3. 複数回コマンド対応
 4. 並列でクライアントからのリクエスト処理
 5. ECHO コマンドの実装
 6. SET, GETコマンドの実装
 7. Expire の実装
 46
  25. 7. Expire の実装
 • Expire
 ◦ SET KEY VALUE 単位

    (時間) で指定する
 ◦ 指定は ex(秒) または px(ミリ秒) で指定する
 ◦ ex) SET lang php px 100
 47
  26. 48

  27. 49

  28. RESP3
 • Redis6.0 以降ではRESP3を使うことができる
 • 主な変更点
 ◦ CRLF -> LF

    に変更
 ◦ データ型の追加
 ▪ Map、Set、Boolean、etc..
 55