この記事では、Redis のファイル イベントについて紹介します。一定の参考価値があります。困っている友人は参照してください。お役に立てれば幸いです。

イベント駆動型
Redis サーバーはイベント駆動型のプログラムであり、 ファイル イベント
と 2 つに分かれています。 時間イベント
- ファイル イベント: ソケットの読み取りおよび書き込み可能なイベント
- 時間指定タスク
[関連する推奨事項:Redisビデオ チュートリアル]
これらはすべて aeEventLoop
構造にカプセル化されています
1 2 3 4 5 6 7 8 9 | typedef struct aeEventLoop {
int stop;
aeFileEvent *events;
aeFireEvent *fired;
aeTimeEvent *timteEventHead;
void *apidata;
aeBeforeSleepProc *beforesleep;
aeBeforeSleepProc *aftersleep;
} aeEventLoop;
|
ログイン後にコピー
イベント ドライバーは実際には while/for
もループします。イベントの発生をループで待機しています
1 2 3 4 5 | while (! eventLoop->stop) {
if (eventLoop->beforesleep != NULL)
eventLoop->beforesleep(eventLoop)
aeProcessEvents(eventLoop, AE_ALL_EVENTS|AE_CALL_AFTER_SLEEP);
}
|
ログイン後にコピー
aeProcessEvents
イベント処理のメイン関数
epoll
Redis クライアント経由TCP ソケット サーバーと対話する場合、ファイル イベントはソケットの読み取り可能および書き込み可能なイベントを指します。一般に、ノンブロッキング モードが使用され、関連する I/O 多重化には、select/epoll/kqueue
などが含まれます。オペレーティング システムが異なれば、実装も異なります。
epoll
を例に挙げると、これは、多数の同時ネットワーク接続を処理するために Linux カーネルによって提案されたソリューションです。 epoll
3 つの API を提供します
1 2 3 | int epoll_create(int size)
|
ログイン後にコピー
1 2 3 4 5 | int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event)
|
ログイン後にコピー
ファイル イベント
Reids は epoll API を直接使用しませんが、4 種類の I/O をサポートします。同時に、O 多重化モデルはこれらのモデルの API をカプセル化します。次に、コンパイル段階で、オペレーティング システムがサポートする I/O 多重化モデルがチェックされ、戦略に従ってどのモデルを再利用するかが決定されます。
epoll を例に挙げると、Redis は次のようにカプセル化されます。
1 2 3 4 5 6 7 8 9 10 | static int aeApiCreate(aeEventLoop *eventLoop)
static int aeApiAddEvent(aeEventLoop *eventLoop, int fd, int mask)
static int aeApiDelEvent(aeEventLoop *eventLoop, int fd, int delmask)
static int aeApiPool(aeEventLoop *eventLoop, struct timeval *tvp)
|
ログイン後にコピー
前述の
eventLoop 構造を思い出してください。そのメンバー apidata は 4 種類の I/O 複数を指します。道路再利用モデル オブジェクト。イベントは監視する必要があるイベント配列を格納し、要素にアクセスするための配列インデックスとしてソケット ファイル記述子を使用します。fired はトリガーされたイベント配列を格納します。
ファイル イベントの構造は次のように定義されます。
1 2 3 4 5 6 | typedef struct aeFileEvent {
int mask;
aeFileProc *rfileProc;
aeFileProc *wfileProc;
void *clientData;
} aeFileEvent;
|
ログイン後にコピー
ファイル作成イベント aeCreateFileEvent の実装を見てください
1 2 3 4 5 6 7 8 9 10 | int aeCreateFileEvent (aeEventLoop *eventLoop, int fd, int mask, aeFileProc *proc, void *clientData) {
aeFileEvent *fe = &eventLoop->evnts[fd];
if (aeApiAddEvent(eventLoop, fd, mask) == -1)
return AE_ERR;
fe->mask |= mask;
if (mask & AE_READABLE) fe->rfileProc = proc;
if (mask & AE_WRITABLE) fe->wfileProc = proc;
fe->clientData = clientData;
return AE_OK;
}
|
ログイン後にコピー
Redis サーバーは、さまざまなファイルを作成することでトランザクションを処理します。次のようなファイル イベント:
起動時にソケットを作成してリッスンし、クライアントの接続を待機します1 | aeCreateFileEvent(server.el, server.ipfd[j], AE_READABLE, acceptTcpHandler, NULL);
|
ログイン後にコピー
クライアントがソケット接続を確立した後、サーバーはクライアントのコマンド要求を待ちます。1 | aeCreateFileEvent(server.el, fd, AE_READABLLE, readQueryFromClient, c);
|
ログイン後にコピー
サーバーがクライアントのコマンド要求を処理した後、コマンド応答はクライアント構造の buf バッファーに一時的にキャッシュされます。クライアントのファイル記述子の書き込み可能なイベントが発生し、コマンド応答が実際にクライアント 1 | aeCreateFileEvent(server.el, c->fd, AE_READABLLE, sendReplyToClient, c);
|
ログイン後にコピー
Redis に送信されます。すべてのイベントの実行は、
aeProcessEvents 関数を通じて制御されます。このうち、ファイルイベントの実行によりブロッキング(epoll_wait)が発生し、ブロッキングイベントが長すぎると時間イベント(タイミング)の実行に支障をきたすため、ファイルイベント実装時に待ち時間を設け、これは、発生した最も古いイベントを計算することによって取得されます
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | int aeProcessEvents(aeEventLoop *eventLoop, int flags) {
shortest = aeSearchNearestTimer(eventLoop);
long long ms = (shortest->when_sec - now_sec) * 1000 + \
shortest->when_ms - now_ms;
numevents = aeApiPoll(eventLoop, ms);
for (j=0; j < numevents; j++) {
aeFileEvent *fe = &eventLoop->events[eventLoop->fired[j]].fd];
}
processed += processTimeEvents(eventLoop);
}
|
ログイン後にコピー
概要
次に、Redis サーバーの対応するコマンドのプロセスを全体的に見てみましょう

aeMain 関数は、aeProcessEvents 関数を呼び出して、ファイル イベントと時間イベントをスケジュールおよび実行します。イベント関連の情報は aeEventLoop に記録されます。まず、aeSearchNearestTimer 関数を通じて最短時間イベントの実行時間間隔 n を取得し、次に aeApiPoll 関数を呼び出して監視対象ソケットを取得し、最後にソケットに対応するイベント処理関数 rfileProc および wfileProc を実行し、最後に時間イベントを実行します。関数 processTimeEvents 。
完全なクライアント/サーバー接続イベント:
- #サーバーはパッケージの AE_READABLE イベントをリッスンします。クライアントが接続要求を送信し、AE_READABLE イベントを生成すると、 、サーバーはクライアントの接続リクエストに応答し、クライアントソケットの AE_READABLE イベントとコマンドリクエスト処理関数 (aeFileProc) を組み合わせ、クライアントはコマンドリクエストをサーバーに送信できます
- サーバーはコマンド要求を送信し、クライアント ソケットは AE_READABLE イベントを生成し、コマンド プロセッサの実行をトリガーします。コマンドを実行すると、対応するコマンド応答が生成されます。サーバーは、クライアント ソケットの AE_WRITABLE イベントとコマンドを組み合わせます。応答処理関数 (aeFileProc) 関連するエンドがコマンド応答を読み取ろうとすると、クライアント ソケットは AE_WRITABLE イベントを生成し、コマンド応答プロセッサの実行をトリガーします。コマンド応答プロセッサがすべてのコマンド応答を書き込むとき、ソケットに入ると、サーバーは、クライアントソケットの AE_WRITABLE イベントとコマンド応答処理関数 (aeFileProc) の間の関連付けに接続します (aeFileProc)
プログラミング関連の知識について詳しくは、プログラミング ビデオをご覧ください。 !
以上がRedis の epoll および file イベントについて説明する記事の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。