この記事では、Redis の関連知識を紹介し、Redis レベルをより高いレベルに引き上げるために、マスター/スレーブ レプリケーション、Sentinel、およびクラスタリングについて説明します。
マスター/スレーブ レプリケーションは、Redis ディストリビューションと高可用性の基礎です。 Redis Assure の。 Redisでは、複製されるサーバーをマスターサーバー(Master)と呼び、マスターサーバーを複製するサーバーをスレーブサーバー(Slave)と呼びます。 [関連する推奨事項: Redis ビデオ チュートリアル ]
マスター/スレーブ レプリケーションの構成は非常にシンプルで、3 つの方法があります (IP マスターを含む)サーバーの IP アドレス/ポート - メイン サーバー Redis サービス ポート):
構成ファイル - redis.conf ファイル、slaveof ip port
コマンド- Redis クライアントは、slaveof ip port
スタートアップ パラメータを実行します——./redis-server --slaveof ip port
Redis のマスター/スレーブ レプリケーション メカニズムは、当初は 6.x バージョンほど完璧ではありませんでしたが、バージョンごとに反復されました。通常、次の 3 つのバージョンの反復を経ています:
#Before 2.8
## に同期コマンドを送信します。
同期作業が完了すると、マスター/スレーブ レプリケーション コマンドの伝播を通じてデータの状態の一貫性を維持する必要があります。下図に示すように、現在のマスターサーバーとスレーブサーバー間の同期作業が完了した後、マスターサービスはクライアントからの DEL K6 命令を受信した後、K6 を削除しますが、この時点ではスレーブサーバーには K6 がまだ存在しており、マスターとスレーブのデータ状態が不一致です。マスターサーバーとスレーブサーバーの一貫したステータスを維持するために、マスターサーバーは自身のデータステータスを変更するコマンドをスレーブサーバーに伝播して実行します。スレーブサーバーも同じコマンドを実行すると、マスターサーバー間のデータステータスはスレーブサーバーに伝播されます。マスターサーバーとスレーブサーバーは一貫性を保ちます。
2.1.3 欠陥
上記のことから、2.8 より前のバージョンのマスター/スレーブ レプリケーションに欠陥は見られませんが、これはネットワークの変動を考慮していないためです。分散を理解している兄弟なら CAP 理論を聞いたことがあるでしょう。CAP 理論は分散ストレージ システムの基礎です。CAP 理論では P (パーティション ネットワーク パーティション) が存在する必要があり、Redis のマスター/スレーブ レプリケーションも例外ではありません。マスターサーバーとスレーブサーバー間でネットワーク障害が発生し、スレーブサーバーとマスターサーバー間の通信が一定時間停止した場合 スレーブサーバーがマスターサーバーに再接続した際、マスターサーバーのデータステータスが低下した場合この間にマスタ/スレーブサーバ間でデータの状態に不整合が発生します。 Redis 2.8 より前のマスター/スレーブ レプリケーション バージョンでは、このデータ状態の不一致を解決する方法は、同期コマンドを再送信することです。同期によりマスター サーバーとスレーブ サーバーのデータ ステータスの一貫性が保証されますが、同期が非常にリソースを消費する操作であることは明らかです。
sync コマンドが実行されると、マスター サーバーとスレーブ サーバーに必要なリソース:
マスター サーバーは BGSAVE を実行して RDB ファイルを生成します。これは大きなサイズを占有します。 CPU、ディスク I/O、およびメモリ リソースの量。
マスター サーバーは生成された RDB ファイルをスレーブ サーバーに送信しますが、これにより多くのネットワーク帯域幅が占有されます。
2.2 バージョン 2.8-4.0
2.2.1 改善点2.8 より前のバージョンの場合、Redis は 2.8 データ ステータスの後にスレーブ サーバーに再接続します。同期が改善されました。改善の方向性は、完全再同期の発生を減らし、可能な限り部分再同期を使用することです。バージョン 2.8 以降では、同期操作を実行するために sync コマンドの代わりに psync コマンドが使用されます。psync コマンドには、完全同期機能と増分同期機能の両方があります。
サーバーからの切断と再接続後に増分同期を実現するために、Redis は 3 つの補助パラメータを追加します。
##レプリケーション オフセットはマスター サーバーとスレーブ サーバーの両方で維持されます
#マスターサーバーはスレーブ サービスにデータを送信し、N バイトのデータを伝播します。マスター サービスのレプリケーション オフセットはスレーブ サーバーから N通常の同期状況は次のとおりです。
マスター サーバーとスレーブ サーバー間のレプリケーション オフセットが等しいかどうかを比較することで、マスター サーバーとスレーブ サーバー間のデータの状態が一貫しているかどうかを知ることができます。
A/B が正常に伝播し、C がサーバーから切断されたと仮定すると、次の状況が発生します。コピーが存在することは明らかです。 offset その後、スレーブ サーバー C が切断され、再接続された後、マスター サーバーは、スレーブ サーバーから失われた 100 バイトのデータを送信するだけで済みます。
しかし、マスター サーバーは、スレーブ サーバーにどのデータが欠けているかをどのようにして知るのでしょうか?2.2.2.2 コピー バックログ バッファ
コピー バックログ バッファは、デフォルト サイズが 1MB の固定長キューです。マスター サーバーのデータ ステータスが変化すると、マスター サーバーはデータをスレーブ サーバーに同期し、コピーをレプリケーション バックログ バッファに保存します。#オフセットを一致させるために、コピー バックログ バッファーはデータの内容を保存するだけでなく、各バイトに対応するオフセットも記録します。
#スレーブ サーバーが切断され、再接続されると、スレーブ サーバーは psync コマンドを通じてそのレプリケーション オフセット (オフセット) をマスター サーバーに送信し、マスター サーバーはこのオフセットを使用できます。増分伝播または完全同期を実行します。
オフセット 1 のデータがまだコピー バックログ バッファーにある場合は、増分同期操作を実行します。
それ以外の場合は、完全同期操作を実行します。同期との一貫性を保つRedis のデフォルトのコピー バックログ バッファ サイズは 1MB ですが、カスタマイズする必要がある場合はどのように設定すればよいですか? 当然のことながら、できる限り増分同期を使用したいと考えていますが、バッファーがあまりにも多くのメモリ領域を占有することは望ましくありません。次に、Redis スレーブ サービスが切断された後の再接続時間 T と、Redis マスター サーバーが 1 秒あたりに受信する書き込みコマンドのメモリ サイズ M を見積もることにより、レプリケーション バックログ バッファーのサイズ S を設定できます。
S = 2 * M * T
ここでの 2 倍の拡張は、ある程度の余地を残すためであることに注意してください。ほとんどのブレークの増分同期を回線の再接続に使用できるようにします。
2.2.2.3 ID
これを見た後、切断と再接続の増分同期はすでに実現できており、次の実行も必要だと思いますか? IDドライ さて?実はこれまで考慮されていなかった、マスターサーバーがダウンした場合にスレーブサーバーが新たなマスターサーバーとして選出される場合もあり、この場合は稼働中のIDを比較することで区別することができます。
完全な psync プロセスは非常に複雑ですが、マスター/スレーブ レプリケーション バージョン 2.8 ~ 4.0 では非常に完璧でした。 psync コマンドによって送信されるパラメータは次のとおりです。
psyncスレーブ サーバーがマスター サーバーを複製していない場合 (マスター サーバーが複製されていない場合)初めてマスター/スレーブがレプリケートされたとき、マスター サーバーは変更される可能性がありますが、スレーブ サーバーは初めて完全に同期されるため)、スレーブ サーバーは次のメッセージを送信します:
psync ? -1完全な psync プロセスは次のとおりです:
Redis バージョン 2.8 ~ 4.0 にはまだ改善の余地がありますが、メイン サーバーを切り替えたときに増分同期を実行できますか?したがって、Redis 4.0 バージョンはこの問題に対処するために最適化され、psync は psync2.0 にアップグレードされました。 pync2.0 はサーバーの実行 ID を放棄し、代わりに replid と replid2 を使用しました。Replid には現在のメイン サーバーの実行 ID が保存され、replid2 には以前のメイン サーバーの実行 ID が保存されます。
レプリケーション オフセット
レプリケーション バックログ
メイン サーバー実行 ID (replid)
最後に実行されているメイン サーバー ID (replid2)
メイン サーバーは replid と replid2 によって解決できます。切り替え時の増分同期の問題は次のとおりです。
replid が現在のメイン サーバーの実行 ID と等しい場合は、増分同期/完全同期の同期方法を決定します
この記事は、次のリソース リストに基づいています:
IP アドレス | ノードの役割 | #ポート||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Redis マスター/センチネル | 6379/26379 | ##192.168.211.105 | |||||||||||||||||||||
Redis スレーブ/センチネル | ##6379/26379 | 192.168.211.106 | |||||||||||||||||||||
Redis スレーブ/センチネル | 6379/26379 | 2. Sentinel の初期化とネットワーク接続Sentinel には特に魔法のような機能はありません。これはより単純な Redis サーバーです。Sentinel が起動すると、さまざまなコマンド テーブルと設定ファイルが読み込まれます。したがって、本質的に Sentinel は少ないコマンドといくつかの特別な機能を備えた Redis サービス。 Sentinel が起動したら、次の手順を実行する必要があります。
struct sentinelState { //当前纪元,故障转移使用 uint64_t current_epoch; // Sentinel监视的主服务器信息 // key -> 主服务器名称 // value -> 指向sentinelRedisInstance指针 dict *masters; // ... } sentinel;2.4 Sentinel が監視するマスター サーバーのリストを初期化する Sentinel が監視するマスター サーバーのリストは、sentinelState のマスター ディクショナリに保存されます。sentinelState が作成されると、マスター サーバーのリストが作成されます。 Sentinel によって監視されているものの初期化が開始されます。
daemonize yes port 26379 protected-mode no dir "/usr/local/soft/redis-6.2.4/sentinel-tmp" sentinel monitor redis-master 192.168.211.104 6379 2 sentinel down-after-milliseconds redis-master 30000 sentinel failover-timeout redis-master 180000 sentinel parallel-syncs redis-master 1sentinelRedisInstance インスタンスは Redis サーバーの情報を保存します (マスターサーバー、スレーブサーバー、Sentinel の情報はすべてこのインスタンスに保存されます)。 typedef struct sentinelRedisInstance { // 标识值,标识当前实例的类型和状态。如SRI_MASTER、SRI_SLVAE、SRI_SENTINEL int flags; // 实例名称 主服务器为用户配置实例名称、从服务器和Sentinel为ip:port char *name; // 服务器运行ID char *runid; //配置纪元,故障转移使用 uint64_t config_epoch; // 实例地址 sentinelAddr *addr; // 实例判断为主观下线的时长 sentinel down-after-milliseconds redis-master 30000 mstime_t down_after_period; // 实例判断为客观下线所需支持的投票数 sentinel monitor redis-master 192.168.211.104 6379 2 int quorum; // 执行故障转移操作时,可以同时对新的主服务器进行同步的从服务器数量 sentinel parallel-syncs redis-master 1 int parallel-syncs; // 刷新故障迁移状态的最大时限 sentinel failover-timeout redis-master 180000 mstime_t failover_timeout; // ... } sentinelRedisInstance;上記の 1 つのマスターと 2 つのスレーブの構成によれば、次のインスタンス構造が得られます。 2.5 メインへのネットワーク接続を作成します。 serverインスタンス構造が初期化された後、Sentinel はマスターへのネットワーク接続の作成を開始します。このステップでは、Sentinel はマスターのクライアントになります。 Sentinel とマスターの間にコマンド接続とサブスクリプション接続が作成されます:
#コマンド接続が作成された後、Sentinel は 10 秒ごとにマスターに INFO コマンドを送信し、マスターの応答情報を使用します。 #マスター自身の情報
メイン サービスに従ってスレーブ サーバーの情報を取得します。Sentinel はスレーブへのネットワーク接続を作成し、ネットワークも作成できます。 Sentinel とスレーブ間の接続 コマンド接続とサブスクリプション接続 当Sentinel和Slave之间创建网络连接之后,Sentinel成为了Slave的客户端,Sentinel也会每隔10秒钟通过INFO指令请求Slave获取服务器信息。 到这一步Sentinel获取到了Master和Slave的相关服务器数据。这其中比较重要的信息如下:
此时实例结构信息如下所示: 2.7 创建Sentinel之间的网络连接此时是不是还有疑问,Sentinel之间是怎么互相发现对方并且相互通信的,这个就和上面Sentinel与自己监视的主从之间订阅_sentinel_:hello频道有关了。 Sentinel会与自己监视的所有Master和Slave之间订阅_sentinel_:hello频道,并且Sentinel每隔2秒钟向_sentinel_:hello频道发送一条消息,消息内容如下:
其中s代码Sentinel,m代表Master;ip表示IP地址,port表示端口、runid表示运行id、epoch表示配置纪元。 多个Sentinel在配置文件中会配置相同的主服务器ip和端口信息,因此多个Sentinel均会订阅_sentinel_:hello频道,通过频道接收到的信息就可获取到其他Sentinel的ip和port,其中有如下两点需要注意:
Sentinel之间不会创建订阅连接,它们只会创建命令连接: 此时实例结构信息如下所示: 3、Sentinel工作Sentinel最主要的工作就是监视Redis服务器,当Master实例超出预设的时限后切换新的Master实例。这其中有很多细节工作,大致分为检测Master是否主观下线、检测Master是否客观下线、选举领头Sentinel、故障转移四个步骤。 3.1 检测Master是否主观下线Sentinel每隔1秒钟,向sentinelRedisInstance实例中的所有Master、Slave、Sentinel发送PING命令,通过其他服务器的回复来判断其是否仍然在线。 sentinel down-after-milliseconds redis-master 30000 在Sentinel的配置文件中,当Sentinel PING的实例在连续down-after-milliseconds配置的时间内返回无效命令,则当前Sentinel认为其主观下线。Sentinel的配置文件中配置的down-after-milliseconds将会对其sentinelRedisInstance实例中的所有Master、Slave、Sentinel都适应。
如果当前Sentinel检测到Master处于主观下线状态,那么它将会修改其sentinelRedisInstance的flags为SRI_S_DOWN 3.2 检测Master是否客观下线当前Sentinel认为其下线只能处于主观下线状态,要想判断当前Master是否客观下线,还需要询问其他Sentinel,并且所有认为Master主观下线或者客观下线的总和需要达到quorum配置的值,当前Sentinel才会将Master标志为客观下线。 当前Sentinel向sentinelRedisInstance实例中的其他Sentinel发送如下命令: SENTINEL is-master-down-by-addr <ip> <port> <current_epoch> <runid>
current_epoch和runid均用于Sentinel的选举,Master下线之后,需要选举一个领头Sentinel来选举一个新的Master,current_epoch和runid在其中发挥着重要作用,这个后续讲解。 接收到命令的Sentinel,会根据命令中的参数检查主服务器是否下线,检查完成后会返回如下三个参数:
3.3 选举领头Sentineldown_state返回1,证明接收is-master-down-by-addr命令的Sentinel认为该Master也主观下线了,如果down_state返回1的数量(包括本身)大于等于quorum(配置文件中配置的值),那么Master正式被当前Sentinel标记为客观下线。 此时,Sentinel会再次发送如下指令: SENTINEL is-master-down-by-addr <ip> <port> <current_epoch> <runid> 此时的runid将不再是0,而是Sentinel自己的运行id(runid)的值,表示当前Sentinel希望接收到is-master-down-by-addr命令的其他Sentinel将其设置为领头Sentinel。这个设置是先到先得的,Sentinel先接收到谁的设置请求,就将谁设置为领头Sentinel。 发送命令的Sentinel会根据其他Sentinel回复的结果来判断自己是否被该Sentinel设置为领头Sentinel,如果Sentinel被其他Sentinel设置为领头Sentinel的数量超过半数Sentinel(这个数量在sentinelRedisInstance的sentinel字典中可以获取),那么Sentinel会认为自己已经成为领头Sentinel,并开始后续故障转移工作(由于需要半数,且每个Sentinel只会设置一个领头Sentinel,那么只会出现一个领头Sentinel,如果没有一个达到领头Sentinel的要求,Sentinel将会重新选举直到领头Sentinel产生为止)。 3.4 故障转移故障转移将会交给领头sentinel全权负责,领头sentinel需要做如下事情:
这其中最难的一步是如果选择最佳的新Master,领头Sentinel会做如下清洗和排序工作:
新的Master产生后,领头sentinel会向已下线主服务器的其他从服务器(不包括新Master)发送SLAVEOF ip port命令,使其成为新master的slave。 到这里Sentinel的的工作流程就算是结束了,如果新master下线,则循环流程即可! 三、集群1、简介Redis集群是Redis提供的分布式数据库方案,集群通过分片(sharding)进行数据共享,Redis集群主要实现了以下目标:
Redis クラスターの学習に関して、まったくの経験がない場合は、まず次の 3 つの記事 (中国語シリーズ) を読むことをお勧めします: Redis クラスターチュートリアル
Redis クラスターの仕様
Redis3 マスター 3 スレーブ擬似クラスター展開
次の内容は、図の 3 つのマスターと 3 つのスレーブ構造に依存しています。以下: リソースリスト:
|
以上がRedis でのマスター/スレーブ レプリケーション、Sentinel、クラスタリングについて説明します。の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。