Redis3.0 クラスター crc16 アルゴリズム PHP クライアント実装方法 (php は、redis3.0 クラスター内の Redis データが配置されている Redis パーティション スロットを取得し、パーティション スロットに基づいてパーティションが配置されている Redis サーバー アドレスを取得します)

WBOY
リリース: 2016-06-13 12:19:32
オリジナル
1915 人が閲覧しました

Redis3.0 クラスター crc16 アルゴリズム PHP クライアント実装方法 (php は、redis3.0 クラスター内の Redis データが配置されている Redis パーティション スロットを取得し、パーティション スロットに基づいてパーティションが配置されている Redis サーバー アドレスを取得します)

データ パーティション

Redis クラスターはデータをパーティション分割し、複数のノードに保存します。つまり、異なるパーティションが異なるノードに保存され、各ノードは複数のパーティションを保存できます。各パーティションは Redis では「ハッシュ スロット」とも呼ばれ、Redis クラスターには合計 16384 個のパーティションが計画されています。
例: クラスター内に 3 つのノードがある場合、ノード A にはパーティション 0 ~ 5460 が含まれます。 , ノード B にはパーティション 5461 ~ 10922 が含まれ、ノード C にはパーティション 10923 ~ 16383 が含まれます。
各キーは一意のパーティションに保存され、各パーティションは実際にはグループのコレクションです。キーの場合、2 つの対応関係は次のとおりです: キーの CRC16 チェック コード 384 = ハッシュ スロット (パーティション マーク) Redis は Memecache のような一貫したハッシュを使用していないことがわかります。コミュニティによると、このルールを使用したキーの配布は非常に均一であり、これはテストでも確認されました。
Redis クラスター内のノードの追加または削除は非常に簡単です。たとえば、新しいノード D を追加する場合、必要なのは、一部のパーティションをノード A、B、C から D に移動することだけです。同様に、Aを削除する場合も、もともとAに属していたパーティションをBとCに移動し、Aが空になったら削除すればよいだけです。
ノード間のパーティションの移動にはサービスを停止する必要がないため、ノードの追加、ノードの削除、またはノードの変更を行うことができます。パーティションの数を増やすには、クラスター サービスを停止する必要はありません。
クライアントがクラスターにアクセスするとき、理論的にはクラスター内のどのノードにもアクセスできます。この時点で、アクセスされたデータはアクセスされたノードに存在しない可能性がありますが、アクセスされたノードはターゲット ノードを自動的に学習し、クライアントのアクセスをリダイレクトできます。つまり、ターゲット ノードのアドレスをクライアントに返し、クライアントはアクセス要求を開始します。また。もちろん、優れたクライアント ツールは、データ パーティションとノード間の対応をキャッシュし、対応が変更されたときに自動的に更新する必要があります。現在、Jedis を含むいくつかのクライアント ツールにこの機能が実装されています。

CRC の概念

CRC の基本原理が理解できない場合は、Wikipedia にアクセスしてください: 巡回冗長検査コード

異なる CRC アルゴリズムは、通常、CRC チェック コード (生成多項式 [G(x)] の最高累乗にも等しい) の桁数に基づいて区別されます (CRC-1、CRC-8 など)。 、CRC-16など。電力が同じ場合、規格が異なれば CRC アルゴリズムも異なります。たとえば、G(x) の最大累乗が 16 の場合、CRC-16-CCITT、CRC-16-IBM などがあります。 Redis は CRC-16-CCITT 標準を使用します。つまり、G(x) は次のとおりです: x16 x12 x5 1.

G(x) の通常の表現は、多項式を 2 進数に変換することです: 1 0001 0000 0010 0001。 16 進数で表すと 0x11021。数値の記憶空間は 17 ビット (2 バイトと 1 ビット、C 言語の実際の記憶域は 3 バイト) です。実際、2 によるモジュロ除算の際、被除数 1 の最上位ビットと除数 1 の最上位ビットは次のようになります。常に整列されている場合、XOR の結果は常に 0 なので省略でき、G(x) = 0x1021 (2 バイト) となり、1 バイトのスペースが節約されます。 Tianshangxing のオリジナルからの抜粋。転載する場合は作者の出典を明記してください


ソースコード

redis の src ディレクトリcrc16.c ファイル:

static const uint16_t crc16tab[256]= {    0x0000,0x1021,0x2042,0x3063,0x4084,0x50a5,0x60c6,0x70e7,    0x8108,0x9129,0xa14a,0xb16b,0xc18c,0xd1ad,0xe1ce,0xf1ef,    0x1231,0x0210,0x3273,0x2252,0x52b5,0x4294,0x72f7,0x62d6,    0x9339,0x8318,0xb37b,0xa35a,0xd3bd,0xc39c,0xf3ff,0xe3de,    0x2462,0x3443,0x0420,0x1401,0x64e6,0x74c7,0x44a4,0x5485,    0xa56a,0xb54b,0x8528,0x9509,0xe5ee,0xf5cf,0xc5ac,0xd58d,    0x3653,0x2672,0x1611,0x0630,0x76d7,0x66f6,0x5695,0x46b4,    0xb75b,0xa77a,0x9719,0x8738,0xf7df,0xe7fe,0xd79d,0xc7bc,    0x48c4,0x58e5,0x6886,0x78a7,0x0840,0x1861,0x2802,0x3823,    0xc9cc,0xd9ed,0xe98e,0xf9af,0x8948,0x9969,0xa90a,0xb92b,    0x5af5,0x4ad4,0x7ab7,0x6a96,0x1a71,0x0a50,0x3a33,0x2a12,    0xdbfd,0xcbdc,0xfbbf,0xeb9e,0x9b79,0x8b58,0xbb3b,0xab1a,    0x6ca6,0x7c87,0x4ce4,0x5cc5,0x2c22,0x3c03,0x0c60,0x1c41,    0xedae,0xfd8f,0xcdec,0xddcd,0xad2a,0xbd0b,0x8d68,0x9d49,    0x7e97,0x6eb6,0x5ed5,0x4ef4,0x3e13,0x2e32,0x1e51,0x0e70,    0xff9f,0xefbe,0xdfdd,0xcffc,0xbf1b,0xaf3a,0x9f59,0x8f78,    0x9188,0x81a9,0xb1ca,0xa1eb,0xd10c,0xc12d,0xf14e,0xe16f,    0x1080,0x00a1,0x30c2,0x20e3,0x5004,0x4025,0x7046,0x6067,    0x83b9,0x9398,0xa3fb,0xb3da,0xc33d,0xd31c,0xe37f,0xf35e,    0x02b1,0x1290,0x22f3,0x32d2,0x4235,0x5214,0x6277,0x7256,    0xb5ea,0xa5cb,0x95a8,0x8589,0xf56e,0xe54f,0xd52c,0xc50d,    0x34e2,0x24c3,0x14a0,0x0481,0x7466,0x6447,0x5424,0x4405,    0xa7db,0xb7fa,0x8799,0x97b8,0xe75f,0xf77e,0xc71d,0xd73c,    0x26d3,0x36f2,0x0691,0x16b0,0x6657,0x7676,0x4615,0x5634,    0xd94c,0xc96d,0xf90e,0xe92f,0x99c8,0x89e9,0xb98a,0xa9ab,    0x5844,0x4865,0x7806,0x6827,0x18c0,0x08e1,0x3882,0x28a3,    0xcb7d,0xdb5c,0xeb3f,0xfb1e,0x8bf9,0x9bd8,0xabbb,0xbb9a,    0x4a75,0x5a54,0x6a37,0x7a16,0x0af1,0x1ad0,0x2ab3,0x3a92,    0xfd2e,0xed0f,0xdd6c,0xcd4d,0xbdaa,0xad8b,0x9de8,0x8dc9,    0x7c26,0x6c07,0x5c64,0x4c45,0x3ca2,0x2c83,0x1ce0,0x0cc1,    0xef1f,0xff3e,0xcf5d,0xdf7c,0xaf9b,0xbfba,0x8fd9,0x9ff8,    0x6e17,0x7e36,0x4e55,0x5e74,0x2e93,0x3eb2,0x0ed1,0x1ef0};uint16_t crc16(const char *buf, int len) {    int counter;    uint16_t crc = 0;    for (counter = 0; counter < len; counter++)            crc = (crc<<8) ^ crc16tab[((crc>>8) ^ *buf++)&0x00FF];    return crc;}
ログイン後にコピー

前述したように、組織ごとに CRC チェック コードの標準が異なります。ここで Redis が採用している標準は CRC-16-CCITT 標準です。 XMODEM で採用 このプロトコルで使用される CRC 標準であるため、一般に XMODEM CRC とも呼ばれます。

このコードのアルゴリズム原理は著者が初めてのものではなく、比較的古典的な「バイトルックアップテーブル方式に基づくCRCチェックコード生成アルゴリズム」です(この記事は「Pick the Stars from」の週末実践的な操作です。 )

PHP クライアントに redis crc16 検証標準を実装する方法.

function redisCRC16 (&$ptr){    $crc_table=array(	    0x0000,0x1021,0x2042,0x3063,0x4084,0x50a5,0x60c6,0x70e7,	    0x8108,0x9129,0xa14a,0xb16b,0xc18c,0xd1ad,0xe1ce,0xf1ef,	    0x1231,0x0210,0x3273,0x2252,0x52b5,0x4294,0x72f7,0x62d6,	    0x9339,0x8318,0xb37b,0xa35a,0xd3bd,0xc39c,0xf3ff,0xe3de,	    0x2462,0x3443,0x0420,0x1401,0x64e6,0x74c7,0x44a4,0x5485,	    0xa56a,0xb54b,0x8528,0x9509,0xe5ee,0xf5cf,0xc5ac,0xd58d,	    0x3653,0x2672,0x1611,0x0630,0x76d7,0x66f6,0x5695,0x46b4,	    0xb75b,0xa77a,0x9719,0x8738,0xf7df,0xe7fe,0xd79d,0xc7bc,	    0x48c4,0x58e5,0x6886,0x78a7,0x0840,0x1861,0x2802,0x3823,	    0xc9cc,0xd9ed,0xe98e,0xf9af,0x8948,0x9969,0xa90a,0xb92b,	    0x5af5,0x4ad4,0x7ab7,0x6a96,0x1a71,0x0a50,0x3a33,0x2a12,	    0xdbfd,0xcbdc,0xfbbf,0xeb9e,0x9b79,0x8b58,0xbb3b,0xab1a,	    0x6ca6,0x7c87,0x4ce4,0x5cc5,0x2c22,0x3c03,0x0c60,0x1c41,	    0xedae,0xfd8f,0xcdec,0xddcd,0xad2a,0xbd0b,0x8d68,0x9d49,	    0x7e97,0x6eb6,0x5ed5,0x4ef4,0x3e13,0x2e32,0x1e51,0x0e70,	    0xff9f,0xefbe,0xdfdd,0xcffc,0xbf1b,0xaf3a,0x9f59,0x8f78,	    0x9188,0x81a9,0xb1ca,0xa1eb,0xd10c,0xc12d,0xf14e,0xe16f,	    0x1080,0x00a1,0x30c2,0x20e3,0x5004,0x4025,0x7046,0x6067,	    0x83b9,0x9398,0xa3fb,0xb3da,0xc33d,0xd31c,0xe37f,0xf35e,	    0x02b1,0x1290,0x22f3,0x32d2,0x4235,0x5214,0x6277,0x7256,	    0xb5ea,0xa5cb,0x95a8,0x8589,0xf56e,0xe54f,0xd52c,0xc50d,	    0x34e2,0x24c3,0x14a0,0x0481,0x7466,0x6447,0x5424,0x4405,	    0xa7db,0xb7fa,0x8799,0x97b8,0xe75f,0xf77e,0xc71d,0xd73c,	    0x26d3,0x36f2,0x0691,0x16b0,0x6657,0x7676,0x4615,0x5634,	    0xd94c,0xc96d,0xf90e,0xe92f,0x99c8,0x89e9,0xb98a,0xa9ab,	    0x5844,0x4865,0x7806,0x6827,0x18c0,0x08e1,0x3882,0x28a3,	    0xcb7d,0xdb5c,0xeb3f,0xfb1e,0x8bf9,0x9bd8,0xabbb,0xbb9a,	    0x4a75,0x5a54,0x6a37,0x7a16,0x0af1,0x1ad0,0x2ab3,0x3a92,	    0xfd2e,0xed0f,0xdd6c,0xcd4d,0xbdaa,0xad8b,0x9de8,0x8dc9,	    0x7c26,0x6c07,0x5c64,0x4c45,0x3ca2,0x2c83,0x1ce0,0x0cc1,	    0xef1f,0xff3e,0xcf5d,0xdf7c,0xaf9b,0xbfba,0x8fd9,0x9ff8,	    0x6e17,0x7e36,0x4e55,0x5e74,0x2e93,0x3eb2,0x0ed1,0x1ef0    );    $crc = 0x0000;    for ($i = 0; $i < strlen($ptr); $i++)        $crc =  $crc_table[(($crc>>8) ^ ord($ptr[$i]))] ^ (($crc<<8) & 0x00FFFF);    return $crc;}$test = chr(0xC6).chr(0xCE).chr(0xA2).chr(0x03); // CRC16-CCITT = 0xE2B4$key1='key1'; $key2='key2';$key3='key3';echo $key1_db=redisCRC16($key1)%16384; //得出在redis(集群)中键值为'key1'的数据存储插槽为9189echo "<br/>";echo $key2_db=redisCRC16($key2)%16384; //得出在redis(集群)中键值为'key2'的数据存储插槽为4998echo "<br/>";echo $key3_db=redisCRC16($key3)%16384; //得出在redis(集群)中键值为'key3'的数据存储插槽为935
ログイン後にコピー

crc16 アルゴリズムに従って、redis データ パーティション スロットを取得して、パーティションが配置されているサーバー アドレスを取得します。

まず、redis パーティションを見てみましょうローカルクラスター環境のスロット範囲 (redis インストールに切り替えるには cd パッケージディレクトリの下の src ディレクトリ [注: redis 解凍パッケージは、インストールされているプログラムのディレクトリ アドレスではありません]):

[[email protected] src]$  ./redis-trib.rb check 127.0.0.1:6384Connecting to node 127.0.0.1:6384: OKConnecting to node 127.0.0.1:6381: OKConnecting to node 127.0.0.1:6383: OKConnecting to node 127.0.0.1:6379: OKConnecting to node 127.0.0.1:6380: OKConnecting to node 127.0.0.1:6382: OK>>> Performing Cluster Check (using node 127.0.0.1:6384)S: 91329dacb2ac77d9295ed46ecaaec6f2c415f7f6 127.0.0.1:6384   slots: (0 slots) slave   replicates 0be8c0b96e23a5843ece9d86cb6d287c92529a8cM: 0be8c0b96e23a5843ece9d86cb6d287c92529a8c 127.0.0.1:6381   slots:10923-16383 (5461 slots) master   1 additional replica(s)S: 53926c1f8b757c6db2d53e12ee94b8c1a761e663 127.0.0.1:6383   slots: (0 slots) slave   replicates beff88cb6dcf6897a6c6de36350032984a4bdf33M: 2fb7a8edab2038d7fabe305dd0099de8bdf1f1e6 127.0.0.1:6379   slots:0-5460 (5461 slots) master   1 additional replica(s)M: beff88cb6dcf6897a6c6de36350032984a4bdf33 127.0.0.1:6380   slots:5461-10922 (5462 slots) master   1 additional replica(s)S: 4738074195072ae29c3f3160382e97c3b56a6392 127.0.0.1:6382   slots: (0 slots) slave   replicates 2fb7a8edab2038d7fabe305dd0099de8bdf1f1e6[OK] All nodes agree about slots configuration.>>> Check for open slots...>>> Check slots coverage...[OK] All 16384 slots covered.
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
以上内容可以看到M位主,S为从(官方要求的redis集群环境必须为6台以上偶数形式的服务器数量,否则无法创建集群环境)从上面输出可以看到分区插槽所在服务器位置: slots:10923-16383 (5461 slots) 127.0.0.1:6381 对应从机 地址为127.0.0.1:6384slots:0-5460 (5461 slots) 127.0.0.1:6379 master 对应从机 地址为127.0.0.1:6381slots:5461-10922 (5462 slots) 127.0.0.1:6380 master对应从机 地址为:127.0.0.1:6383
ログイン後にコピー
一共三台主分区,可以通过 取得的插槽位置 定位到 不同的redis分区上去取对应的数据,一但主分区数量有变动,就需要根据实际分区数量重新定位插槽分区范围存取redis地址根据<strong><span style="color:#ff0000;">ceil(redisCRC16(redis $key值)%16384 / intval(16384/集群master数)) 得到 对应 的 redis集群服务器顺序 地址</span></strong>,并根据对应区间地址指向到对应的 redis区间master地址即可,注意:如果对应的master区间挂掉了,也不必担心,只需要将地址变更为master主区间对应的 slave从区间服务器地址即可一样取得redis数据,而这正是redis3.0后续版本的精妙之处,不需要第三方插件即可在服务端制动实现集群主备模式,不会影响用户正常读取,当然如果是master和对应的slave一起挂掉了那就没办法了,通常这种几率是很小很小的 小到可以忽略即可...关于redis添加删除集群节点的方法请参阅相关资料,摘取天上星 原创,转载请标明作者出处,本文暂不详叙!
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート