1

最近、redis のソース コードを読みました。現在、ネットワーク コードを勉強しています。

Redis は、ネットワーク データの読み取り/書き込みに非ブロック モードと epoll (または類似のもの) を使用します。データ読み込みイベントが到着すると、「readQueryFromClient」関数が呼び出され、この関数内でリクエストデータがバッファに読み込まれます。

「readQueryFromClient」関数では、実際にデータが到着した場合、1 つの「read」関数によってデータがバッファに読み込まれ、リクエストが処理されます。

 nread = read(fd, c->querybuf+qblen, readlen); // **one read function**
//... some other codes to check read function retuen value
processInputBuffer(c);// **request will be handled in this function**

私の質問は次のとおりです: redis は、1 回の「読み取り」関数呼び出しだけですべての要求データをバッファーに読み込むことができるようにするにはどうすればよいですか?

4

1 に答える 1

2

processInputBuffer(c);//リクエストはこの関数で処理されます

その部分は真実ではありません。Redis プロトコルは、渡されるデータのすべてのチャンクの長さを含めるように設計されています。したがって、サーバーは、完全なリクエストを作成するために読み取る必要があるデータの量を常に認識しています。processInputBufferどちらprocessInlineBufferprocessMultibulkBuffer返されない場合 (つまり、リクエスト ターミネータがバッファ内REDIS_OKに見つからなかった/十分な引数がない場合)、制御は単に関数の外に出ます。このprocessInputBuffer場合、クライアント バッファのチャンクをいっぱいにして、解析状態を更新するだけでした。次に、イベント ループの次の反復で、 への呼び出しaeProcessEventsで、ソケット バッファに未読のデータが残っている場合、readQueryFromClientコールバックが再度トリガーされ、残りのデータが解析されます。

于 2013-08-13T11:37:59.003 に答える