Redis源码解析1
前言 Redis(REmoteDIctionaryServer)是一个由Salvatore Sanfilippo写的key-value存储系统。 它有以下特点: 总体结构 Redis是一个单线程的服务器(除了写磁盘会开子进程,VM管理会开线程,先忽略这两块) 所以,它的服务器启动流程非常清晰,看下图,不再
前言
Redis(REmote DIctionary Server)是一个由Salvatore Sanfilippo写的key-value存储系统。
它有以下特点:
Redis是一个单线程的服务器(除了写磁盘会开子进程,VM管理会开线程,先忽略这两块)
所以,它的服务器启动流程非常清晰,看下图,不再赘述
事件循环 1. 数据结构
通过 aeEventLoop 结构来表示一个事件框架,美国服务器,分析如下:
1 typedef struct aeEventLoop { timeEventNextId; aeFileEvent events[AE_SETSIZE]; aeFiredEvent fired[AE_SETSIZE]; aeTimeEvent *timeEventHead; stop; aeBeforeSleepProc *beforesleep; 10 } aeEventLoop;
2. 事件函数分发流程redis支持 epoll、kqueue、select 三种网络模型
网络框架的代码实现主要在以下几个文件中:
ae.c / ae.h // 网络框架
ae_epoll.c // epoll模型的实现
ae_kqueue.c // kqueue模型的实现
ae_select.c // select模型的实现
程序选择哪一种,网站空间,是在编译期确定的
1 1 file ae.c #ifdef HAVE_EPOLL #ifdef HAVE_KQUEUE #include
框架函数非常简单,从初始化到结束,主要的函数就3个
aeCreateEventLoop、aeMain、aeDeleteEventLoop
其中,aeMain是事件循环的主体函数,它又会调用 aeProcessEvents函数
三个主体函数会调用 aeApiCreate、aeApiPool、aeApiFree三个接口函数进行处理
这三个接口函数又会映射到具体的某一种网络模型中,而这是在编译期确定下来的
具体如下图所示:
添加删除事件,由
aeCreateFileEvent、aeDeleteFileEvent函数完成,其函数分发流程如下图:
1. 在服务器初始化时,建立侦听socket,并绑定IP、Port
支持 TCP连接 与本机的unixSocket连接
1 if (server.port != 0) { 2 server.ipfd = anetTcpServer(server.neterr,server.port,server.bindaddr); 3 ... ... 4 } 5 if (server.unixsocket != NULL) { server.sofd = anetUnixServer(server.neterr,server.unixsocket,server.unixsocketperm); 8 ... ... 9 }
2. 侦听socket绑定到事件句柄
1 if (server.ipfd > 0 && aeCreateFileEvent(server.el,server.ipfd,AE_READABLE, ); 3 if (server.sofd > 0 && aeCreateFileEvent(server.el,server.sofd,AE_READABLE, );
其中“acceptTcpHandler”、“acceptUnixHandler” 是事件回调函数
当新连接到达时,会触发进入这两个函数
3. 再来看看 accept***Handler 里做了什么
1 void acceptTcpHandler(aeEventLoop *el, int fd, void *privdata, int mask) { 2 int cport, cfd; 3 char cip[128]; 4 REDIS_NOTUSED(el); 5 REDIS_NOTUSED(mask); 6 REDIS_NOTUSED(privdata); cfd = anetTcpAccept(server.neterr, fd, cip, &cport); 10 if (cfd == AE_ERR) { , server.neterr); 12 return; 13 } , cip, cport); }
acceptCommonHandler中做的事很简单,调用 CreateClient函数,创建新的redisClient对象
acceptCommonHandler(int fd) { 2 redisClient *c; 3 if ((c = createClient(fd)) == NULL) { ); ; 7 } 8 ... ... 9 }
在 createClient函数中,将新连接绑定到事件循环中
1 redisClient *createClient(int fd) { 2 redisClient *c = zmalloc(sizeof(redisClient)); 3 c->bufpos = 0; 4 5 anetNonBlock(NULL,fd); 6 anetTcpNoDelay(NULL,fd); 7 if (aeCreateFileEvent(server.el,fd,AE_READABLE, { 10 close(fd); 11 zfree(c); 12 return NULL; 13 }
当连接上有数据到达时,便会触发 readQueryFromClient函数,进行实际的网络数据读取与处理
3. Timer事件Redis将所有Timer绑定到事件循环中进行处理
通过函数 aeCreateTimeEvent 创建新的Timer事件
每一帧事件循环中,通过processTimeEvents函数进行处理

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

AI Hentai Generator
AIヘンタイを無料で生成します。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック









Redisクラスターモードは、シャードを介してRedisインスタンスを複数のサーバーに展開し、スケーラビリティと可用性を向上させます。構造の手順は次のとおりです。異なるポートで奇妙なRedisインスタンスを作成します。 3つのセンチネルインスタンスを作成し、Redisインスタンスを監視し、フェールオーバーを監視します。 Sentinel構成ファイルを構成し、Redisインスタンス情報とフェールオーバー設定の監視を追加します。 Redisインスタンス構成ファイルを構成し、クラスターモードを有効にし、クラスター情報ファイルパスを指定します。各Redisインスタンスの情報を含むnodes.confファイルを作成します。クラスターを起動し、CREATEコマンドを実行してクラスターを作成し、レプリカの数を指定します。クラスターにログインしてクラスター情報コマンドを実行して、クラスターステータスを確認します。作る

Redisは、キーの一意性を確保するために5つの戦略を使用します。1。名前空間分離。 2。ハッシュデータ構造。 3.データ構造を設定します。 4。文字列キーの特殊文字。 5。LUAスクリプト検証。特定の戦略の選択は、データ組織、パフォーマンス、およびスケーラビリティ要件に依存します。

Redisはハッシュテーブルを使用してデータを保存し、文字列、リスト、ハッシュテーブル、コレクション、注文コレクションなどのデータ構造をサポートします。 Redisは、スナップショット(RDB)を介してデータを維持し、書き込み専用(AOF)メカニズムを追加します。 Redisは、マスタースレーブレプリケーションを使用して、データの可用性を向上させます。 Redisは、シングルスレッドイベントループを使用して接続とコマンドを処理して、データの原子性と一貫性を確保します。 Redisは、キーの有効期限を設定し、怠zyな削除メカニズムを使用して有効期限キーを削除します。

Redis Clusterは、Redisインスタンスの水平拡張を可能にする分散展開モデルであり、ノード間通信、ハッシュスロット部門キースペース、ノード選挙、マスター奴隷レプリケーション、コマンドリダイレクトを通じて実装されます。ハッシュスロット:キースペースをハッシュスロットに分割して、キーの責任ノードを決定します。ノード選挙:少なくとも3つのマスターノードが必要であり、選挙メカニズムを通じて1つのアクティブマスターノードのみが保証されます。マスタースレーブレプリケーション:マスターノードはリクエストの書き込みを担当し、スレーブノードはリクエストとデータレプリケーションを読む責任があります。コマンドリダイレクト:クライアントはキーを担当するノードに接続し、ノードは誤ったリクエストをリダイレクトします。トラブルシューティング:障害検出、オフラインのマーク、および再

Redisバージョン番号を表示するには、次の3つの方法を使用できます。(1)情報コマンドを入力し、(2) - versionオプションでサーバーを起動し、(3)構成ファイルを表示します。

Redisのすべてのキーを表示するには、3つの方法があります。キーコマンドを使用して、指定されたパターンに一致するすべてのキーを返します。スキャンコマンドを使用してキーを繰り返し、キーのセットを返します。情報コマンドを使用して、キーの総数を取得します。

Redis Orderedセット(ZSET)は、並べ替えられた要素を保存し、関連するスコアでソートするために使用されます。 zsetを使用する手順には次のものがあります。1。zsetを作成します。 2。メンバーを追加します。 3.メンバースコアを取得します。 4。ランキングを取得します。 5.ランキング範囲のメンバーを取得します。 6.メンバーを削除します。 7.要素の数を取得します。 8。スコア範囲のメンバーの数を取得します。

Redisコマンドラインツール(Redis-Cli)を使用して、次の手順を使用してRedisを管理および操作します。サーバーに接続し、アドレスとポートを指定します。コマンド名とパラメーターを使用して、コマンドをサーバーに送信します。ヘルプコマンドを使用して、特定のコマンドのヘルプ情報を表示します。 QUITコマンドを使用して、コマンドラインツールを終了します。
