目次
go-redis接続クラスターの構成、特にアドレス配列
転送元:https://blog.csdn.net/pengpengzhou/article/details/105559884
client := redis.NewClusterClient(&redis.ClusterOptions{
//-------------------------------------------------------------------------------------------
//集群相关的参数
//集群节点地址,理论上只要填一个可用的节点客户端就可以自动获取到集群的所有节点信息。但是最好多填一些节点以增加容灾能力,因为只填一个节点的话,如果这个节点出现了异常情况,则Go应用程序在启动过程中无法获取到集群信息。
Addrs: []string{"127.0.0.1:7000", "127.0.0.1:7001", "127.0.0.1:7002", "127.0.0.1:7003", "127.0.0.1:7004", "127.0.0.1:7005"},
MaxRedirects: 8, // 当遇到网络错误或者MOVED/ASK重定向命令时,最多重试几次,默认8
//只含读操作的命令的"节点选择策略"。默认都是false,即只能在主节点上执行。
ReadOnly: false, // 置为true则允许在从节点上执行只含读操作的命令
// 默认false。 置为true则ReadOnly自动置为true,表示在处理只读命令时,可以在一个slot对应的主节点和所有从节点中选取Ping()的响应时长最短的一个节点来读数据
RouteByLatency: false,
// 默认false。置为true则ReadOnly自动置为true,表示在处理只读命令时,可以在一个slot对应的主节点和所有从节点中随机挑选一个节点来读数据
RouteRandomly: false,
//用户可定制读取节点信息的函数,比如在非集群模式下可以从zookeeper读取。
//但如果面向的是redis cluster集群,则客户端自动通过cluster slots命令从集群获取节点信息,不会用到这个函数。
ClusterSlots: func() ([]ClusterSlot, error) {
},
//钩子函数,当一个新节点创建时调用,传入的参数是新建的redis.Client
OnNewNode: func(*Client) {
},
//------------------------------------------------------------------------------------------------------
//ClusterClient管理着一组redis.Client,下面的参数和非集群模式下的redis.Options参数一致,但默认值有差别。
//初始化时,ClusterClient会把下列参数传递给每一个redis.Client
//钩子函数
//仅当客户端执行命令需要从连接池获取连接时,如果连接池需要新建连接则会调用此钩子函数
OnConnect: func(conn *redis.Conn) error {
fmt.Printf("conn=%v\n", conn)
return nil
},
Password: "",
//每一个redis.Client的连接池容量及闲置连接数量,而不是cluterClient总体的连接池大小。实际上没有总的连接池
//而是由各个redis.Client自行去实现和维护各自的连接池。
PoolSize: 15, // 连接池最大socket连接数,默认为5倍CPU数, 5 * runtime.NumCPU
MinIdleConns: 10, //在启动阶段创建指定数量的Idle连接,并长期维持idle状态的连接数不少于指定数量;。
//命令执行失败时的重试策略
MaxRetries: 0, // 命令执行失败时,最多重试多少次,默认为0即不重试
MinRetryBackoff: 8 * time.Millisecond, //每次计算重试间隔时间的下限,默认8毫秒,-1表示取消间隔
MaxRetryBackoff: 512 * time.Millisecond, //每次计算重试间隔时间的上限,默认512毫秒,-1表示取消间隔
//超时
DialTimeout: 5 * time.Second, //连接建立超时时间,默认5秒。
ReadTimeout: 3 * time.Second, //读超时,默认3秒, -1表示取消读超时
WriteTimeout: 3 * time.Second, //写超时,默认等于读超时,-1表示取消读超时
PoolTimeout: 4 * time.Second, //当所有连接都处在繁忙状态时,客户端等待可用连接的最大等待时长,默认为读超时+1秒。
//闲置连接检查包括IdleTimeout,MaxConnAge
IdleCheckFrequency: 60 * time.Second, //闲置连接检查的周期,无默认值,由ClusterClient统一对所管理的redis.Client进行闲置连接检查。初始化时传递-1给redis.Client表示redis.Client自己不用做周期性检查,只在客户端获取连接时对闲置连接进行处理。
IdleTimeout: 5 * time.Minute, //闲置超时,默认5分钟,-1表示取消闲置超时检查
MaxConnAge: 0 * time.Second, //连接存活时长,从创建开始计时,超过指定时长则关闭连接,默认为0,即不关闭存活时长较长的连接
})
defer client.Close()
特に:
理論的には、クラスターノードアドレスは、使用可能なノードクライアントに入力するだけで、クラスター内のすべてのノード情報を自動的に取得します。ただし、災害耐性を高めるには、より多くのノードを入力することをお勧めします。1つのノードのみが入力された場合、このノードに異常な状況があると、Goアプリケーションは起動プロセス中にクラスター情報を取得できません。
追加:[] string {"127.0.0.1:7000"、 "127.0.0.1:7001"、 "127.0.0.1:7002"、 "127.0.0.1:7003"、 "127.0.0.1:7004"、 "127.0.0.1 :7005 "}、
Redisフェイルオーバーの原則
転送元:https://blog.csdn.net/tr1912/article/details/81265007
前提
次の図に示すように、3つのマスターと3つのスレーブのクラスターが構築されます。
そして、クラスターは実行されています
1.障害シミュレーション
最初にメインサービスを停止し、何が変わるかを確認します。
7002メインサーバーを停止しました。
すぐに彼のスレーブ7004サーバーでこれらを見るでしょう
次に、他のマスターサーバーはこれらを参照します。
これは、ノードがダウンし、そのハッシュスロットがリサイクルされ、新しいマスターが選出されることを意味します。
他のスレーブは、ダウンしていたスレーブをアクセス障害としてマークしました
次に、ダウンしていたマスターマシンのスレーブでこれらを確認できます。
この奴隷は選挙の進捗状況を知っており、主人に選出されたことがわかります。これまでのところ、主人の選挙はすべて終わっています。
次に、元のホスト7002を起動します
ホスト7004を見ると、最初にホスト7002を到達可能としてマークし、次にデータを同期していることがわかりました。データに記録されたpidによると
他のマシンはそれを到達可能としてマークするだけです:
今回は、マスターマシンとスレーブマシンの両方を停止して、何が起こるかを確認する必要があります。
最初にスレーブ7002を停止しましょう:
彼のホスト:
その他のマシン:
次に、7004ホストを停止します。
他の奴隷:
その他のホスト:
これは、ノード内の1つのシャードの機能が完全に停止している限り、クラスター全体が接続できない状態になっていることがわかります。
次に、最初にスレーブノード7002を起動します。
7002はマスターノードをスキャンしています
他のノードは、7002が以前に復元されたときと同じであり、使用可能としてマークされています。
この時点で7004ノードを開始します。
7002が7004に接続され、データの波が同期されていることがわかります。
他のノードは、このノードが接続を復元したことを示し、その後、クラスター全体が復元されます。
三、メカニズムの解釈
これがredisクラスターのフェイルオーバーメカニズムです。redisの各ノードはping / pongを介して通信し、スロットの情報とノードステータス情報を再ブロードキャストし、このアクションによって障害検出も検出されます。これは、合計で次の手順に分けられます。
1.主観的オフライン:ノードは別のノードが利用できないと考えてオフラインになります。これが最初の実験です。7002ノードが最初に切断されると、7002が到達不能になると7004はすぐに7004を見つけます。思考の状態。
2.目的オフライン:ノードが真にオフラインとしてマークされ、クラスター内の複数のノードがそのノードを使用不可と見なす状態を指します。たとえば、最初の実験でしばらくすると、他のノードは7002を失敗状態としてマークします。
3.障害回復:障害が発生したノードが客観的にオフラインになった後、オフラインノードがスロットを保持するマスターノードである場合、クラスターの高可用性を確保するために、スレーブノードの1つを選択して置き換える必要があります。オフラインマスターノードのすべてのスレーブノードが障害回復を担当します。スレーブノードが、複製されたマスターノードが内部タイミングタスクを通じて目的のオフラインに入るのを検出すると、障害回復プロセスがトリガーされます。
1) 認定チェック:各スレーブノードは、マスターノードとの最後の切断時間をチェックして、障害が発生したマスターノードを置き換える資格があるかどうかを判断する必要があります。スレーブノードとマスターノード間の切断時間がcluster-node-time * cluster-slave-validity-factorを超える場合、現在のスレーブノードはフェイルオーバーの対象になりません。パラメータcluster-slavevalidity-factorは、スレーブノードの有効性係数に使用されます。デフォルトは10です。
2)選出時間の準備:スレーブノードがフェイルオーバーの対象となると、失敗選出をトリガーする時間が更新され、フォローアッププロセスはその時間に達した後にのみ実行できます。ここで遅延トリガーメカニズムが採用されている理由は、主に、複数のスレーブノードに対して異なる遅延選択時間を使用することによって優先度の問題をサポートするためです。レプリケーションオフセットが大きいほど、スレーブノードの遅延が少なくなるため、障害が発生したマスターノードを置き換える優先度を高くする必要があります。コピーオフセットが最大のすべてのスレーブノードは、事前に障害選択プロセスをトリガーします。
マスターノードbが目的をオフラインにした後、その3つのスレーブノードは、自身のレプリケーションオフセットに従って遅延選択時間を設定します。たとえば、レプリケーションオフセットが最大のノードであるスレーブb-1は、実行を1秒間遅延させて、レプリケーション遅延が少ないスレーブノード選択の開始を優先します。
3)選挙を開始する:
スレーブノードのタイミングタスクの検出が失敗の選択時間(failover_auth_time)に達すると、選択プロセスは次のようになります。
(1)構成エポックの更新:構成エポックは、増加するだけで減少しない整数です。各マスターノードは、現在のマスターノードのバージョンを示す構成エポック(clusterNode.configEpoch)を維持します。すべてのマスターの構成エポックノードは等しくありません。スレーブノードはマスターノードの構成エポックをコピーします。クラスター全体がグローバル構成エポック(clusterState.currentエポック)を維持します。これは、クラスター内のすべてのマスターノードの構成エポックの最大バージョンを記録するために使用されます。cluster infoコマンドを実行して、構成エポック情報を表示します。クラスター内で重要なクリティカルイベントが発生する限り、エポックの数が増えるため、スレーブを選択するときは、エポックの数が最も多いスレーブを選択する必要があります。
(2)選挙メッセージのブロードキャスト:クラスター内の選挙メッセージ(FAILOVER_AUTH_REQUEST)をブロードキャストし、送信されたメッセージのステータスを記録して、スレーブノードが構成エポック内で1つの選挙のみを開始できるようにします。メッセージの内容はpingメッセージに似ていますが、タイプがFAILOVER_AUTH_REQUESTに変更されます。
4)選挙投票:ハッシュスロットを保持しているマスターノードのみが投票に参加でき、各マスターノードは投票する権利を持ちます。クラスター内にマスターノードがN個ある場合、1つのスレーブノードがN /を取得する限り2 +1投票は勝者と見なされます。
Ps。フェイルオーバーしたマスターノードも投票数にカウントされます。クラスター内のノードの規模が3つのマスターと3つのスレーブであると仮定すると、1つのマシンに2つのマスターノードが展開されます。このマシンがダウンすると、スレーブノードがダウンします。マスターノードから3/2 + 1票を収集できないと、フェイルオーバーが失敗します。この質問は、障害検出リンクにも当てはまります。したがって、クラスターをデプロイするときは、シングルポイントの問題を回避するために、すべてのマスターノードを少なくとも3台の物理マシンにデプロイする必要があります。
投票の無効化:各構成エポックは選択サイクルを表します。投票の開始後、ノードがcluster-node-timeout * 2内で十分な数の投票を取得しない場合、選択は無効になります。スレーブノードは構成エポックをインクリメントし、選択が成功するまで次の投票ラウンドを開始します。
5)マスターノードを交換します
スレーブノードが十分な票を集めたら、マスターノードを置き換える操作をトリガーします。
- 現在のスレーブノードはレプリケーションをキャンセルし、マスターノードになります。
- clusterDelSlot操作を実行して、障害が発生したマスターノードの原因となっているスロットをキャンセルし、clusterAddSlotを実行して、これらのスロットをそれ自体に委任します。
- 独自のpongメッセージをクラスターにブロードキャストして、クラスター内のすべてのノードに、現在のスレーブノードがマスターノードになり、障害が発生したマスターノードのスロット情報を引き継いだことを通知します。