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

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

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

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 までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート