Twitter の Twemproxy は現在市場で最も広く使用されており、主に Redis クラスター サービスに使用されています。 Redis はシングルスレッドであり、公式クラスターはあまり安定しておらず、広く使用されているわけではありません。 Twemproxy はプロキシ シャーディング メカニズムであり、プロキシとして複数のプログラムからのアクセスを受け入れ、ルーティング ルールに従ってバックグラウンドの各 Redis サーバーに転送し、元のルートに戻すことができます。このソリューションは、単一の Redis インスタンスの収容能力の問題をうまく解決します。もちろん、Twemproxy 自体も単一ポイントであり、高可用性ソリューション (または LVS) として Keepalived を使用する必要があります。 Twemproxy を通じて、複数のサーバーを使用して Redis サービスを水平方向に拡張でき、単一障害点を効果的に回避できます。 Twemproxy を使用すると、より多くのハードウェア リソースが必要になり、Redis のパフォーマンスがある程度低下します (twitter テストでは約 20%) が、システム全体の HA を改善するには非常に費用対効果が高くなります。実際、twemproxy は redis プロトコルを実装するだけでなく、memcached プロトコルも実装します。つまり、twemproxy は redis をプロキシできるだけでなく、memcached もプロキシすることができます。
1) アクセス ノードを外部に公開すると、プログラムの複雑さが軽減されます。
2) 障害が発生したノードの自動削除をサポートします。ノードを再接続するまでの時間を設定し、接続数を設定した後にノードを削除できます。この方法はキャッシュ ストレージに適しています。そうしないとキーが失われます。
3) HashTag の設定のサポート HashTag を通じて、同じインスタンスに 2 つの KEYhash を設定できます。
4) 複数のハッシュ アルゴリズムとバックエンド インスタンスの重みを設定できます。
5) Redis との直接接続の数を減らします。Redis との長い接続を維持し、エージェントとバックエンド間の各 Redis 接続の数を設定し、バックエンド上の複数の Redis インスタンスに自動的にシャーディングします。
6) 単一点の問題を回避します。複数のプロキシ レイヤを並行してデプロイでき、クライアントは利用可能なプロキシ レイヤを自動的に選択します。
7) 高スループット: 接続多重化、メモリ多重化、Redis パイプラインと Redis への統合リクエストで構成される複数の接続リクエスト。
1) 集合の部分交差や補数の取得など、複数の値に対する演算はサポートされていません。
2) Redis トランザクション操作はサポートされていません。
3) 適用されたメモリは解放されません。すべてのマシンに大きなメモリが必要であり、定期的に再起動する必要があります。そうしないと、クライアント接続エラーが発生します。
4) ノードの動的な追加と削除はサポートされていないため、構成を変更した後は再起動が必要です。
5) ノードを変更するとき、システムは既存のデータを再割り当てしません。データ移行用の独自のスクリプトを作成しない場合、一部のキーが失われます (キー自体は特定の Redis 上に存在しますが、キーは失われます)ハッシュ化されている)他のノードに影響を与え、「損失」を引き起こします)。
6) 重みはキーのハッシュ結果に直接影響します。ノードの重みを変更すると、一部のキーが失われます。
7) デフォルトでは、Twemproxy はシングルスレッドで実行されますが、Twemproxy を使用しているほとんどの企業は、独自に二次開発を行ってマルチスレッドに変更します。
一般的に、twemproxy は依然として非常に信頼性が高く、パフォーマンスは低下しますが、依然として比較的価値があり、長期間にわたってテストされており、広く使用されています。詳細については、公式ドキュメントを参照してください。また、twemproxy は静的クラスターにのみ適しており、動的なノードの追加や削除、手動による負荷調整が必要なシナリオには適していないため、直接使用する場合は開発や改善作業が必要になります。 https://github.com/wandoulabs/codis このシステムは twemproxy をベースに動的データ移行などの機能を追加していますが、具体的な使用方法についてはさらなるテストが必要です。
最初のタイプ: 単一ノード Twemproxy
ps: ハードウェア リソースを節約しますが、シングル ポイントになる傾向があります。失敗。
2 番目のタイプ: 高可用性 Twemproxy
PS: リソースの半分が無駄になりますが、ノードは高可用性です。
3 番目のタイプ: 負荷分散 Twemproxy
PS: 大規模な Redis または Memcached アプリケーション シナリオの場合は、Twemproxy 負荷分散シナリオを実行できます。つまり、高可用性 Twemproxy に基づいて LVS ノードを追加し、LVS (Linux 仮想サーバー) を使用して Twemproxy の負荷分散を実行します。LVS は 4 層の負荷分散テクノロジーであり、非常に強力なプロキシ機能を備えています。詳細については、こちらをご覧ください。このブログの LVS の章を参照してください。しかし、LVS を使用すると、Twemproxy の問題や単一障害点が再び発生するため、LVS の高可用性を実現する必要があります。 OSPF ルーティング テクノロジを使用して、LVS は負荷分散も実現できます。そして、このアーキテクチャは私が現在仕事で使用しているアーキテクチャです。
さらに、上記のアーキテクチャ方法のいずれを使用しても、Redis の単一障害点の問題は回避できません。また、Redis の永続化ではハードウェア障害の問題を回避できません。 Redis データ アクセスの中断のないことを保証する必要がある場合は、Redis クラスター モードを使用する必要があります。クラスター モードは現在、JAVA を適切にサポートしており、仕事で広く使用されています。
1.Twemproxy をダウンロードします
次のステートメントを 1 つの文に書き直してください: 次のコマンドを使用して、twemproxy リポジトリのクローンをローカル マシンに作成します: git clone https://github.com/twitter/twemproxy.git 書き換え後: ローカル コンピューターで次のコマンドを使用します: git clone https://github.com/twitter/twemproxy.git を使用して、twemproxy リポジトリのクローンを作成します
2. Twemproxy をインストールします
Twemproxy は Autoconf を使用する必要がありますコンパイルと設定用。 GNU Autoconf は、Bourne シェルでソフトウェアをコンパイル、インストール、パッケージ化するための構成スクリプトを作成するためのツールです。 Autoconf はプログラミング言語に制限されず、C、C++、Erlang、Objective-C で一般的に使用されます。構成スクリプトは、特定のシステムへのソフトウェア パッケージのインストールを制御します。一連のテストを実行することにより、構成スクリプトはテンプレートからメイクファイルとヘッダー ファイルを生成し、必要に応じてパッケージを調整して特定のシステムに適したものにします。 Autoconf は、Automake および Libtool とともに、GNU Build System を形成します。 Autoconf は、Free Software Foundation でのプログラミング作業をサポートするために、1991 年の夏に David McKenzie によって作成されました。 Autoconf には、複数の人が作成した改良されたコードが組み込まれており、最も広く使用されている無料のコンパイルおよび構成ソフトウェアとなっています。
autoreconf を使用して twemproxy のコンパイルと構成を開始しましょう:
[root@www twemproxy]# autoreconfconfigure.ac:8: error: Autoconf version 2.64 or higher is required configure.ac:8: the top level autom4te: /usr/bin/m4 failed with exit status: 63 aclocal: autom4te failed with exit status: 63 autoreconf: aclocal failed with exit status: 63 [root@www twemproxy]# autoconf --versionautoconf (GNU Autoconf) 2.63
autoreconf のバージョンが低すぎるというメッセージが表示されます。上記では autoconf 2.63 バージョンが使用されているため、autoconf 2.69 バージョンをダウンロードしましょう。コンパイルとインストール。 CentOS6 の場合はデフォルト バージョンが 2.63、CentOS7 の場合はデフォルト バージョンが 2.69、Debian8 または Ubuntu16 の場合はデフォルト バージョンが 2.69 である必要があることに注意してください。とにかく、autoreconf の実行時にエラーが報告された場合は、バージョンが古いため、コンパイルしてインストールする必要があることを意味します。
[root@www ~]# wget http://ftp.gnu.org/gnu/autoconf/autoconf-2.69.tar.gz[root@www ~]# tar xvf autoconf-2.69.tar.gz[root@www ~]# cd autoconf-2.69[root@www autoconf-2.69]# ./configure --prefix=/usr[root@www autoconf-2.69]# make && make install[root@www autoconf-2.69]# autoconf --versionautoconf (GNU Autoconf) 2.69
[root@www ~]# cd /root/twemproxy/[root@www twemproxy]# autoreconf -fvi[root@www twemproxy]# ./configure --prefix=/etc/twemproxy CFLAGS="-DGRACEFUL -g -O2" --enable-debug=full[root@www twemproxy]# make && make install
autoreconf -fvi で次のエラーが報告された場合は、libtool ツールをインストールする必要があり、libtool に依存する必要があります。 (CentOSの場合はyumを直接使用してlibtoolをインストールするだけです。Debianの場合はapt-get install libtoolを使用してください。)
autoreconf: Entering directory `.' autoreconf: configure.ac: not using Gettext autoreconf: running: aclocal --force -I m4 autoreconf: configure.ac: tracing autoreconf: configure.ac: adding subdirectory contrib/yaml-0.1.4 to autoreconf autoreconf: Entering directory `contrib/yaml-0.1.4'autoreconf: configure.ac: not using Autoconf autoreconf: Leaving directory `contrib/yaml-0.1.4' autoreconf: configure.ac: not using Libtool autoreconf: running: /usr/bin/autoconf --force configure.ac:36: error: possibly undefined macro: AC_PROG_LIBTOOL If this token and others are legitimate, please use m4_pattern_allow. See the Autoconf documentation. autoreconf: /usr/bin/autoconf failed with exit status: 1
[root@www twemproxy]# mkdir /etc/twemproxy/conf[root@www twemproxy]# cat /etc/twemproxy/conf/nutcracker.ymlredis-cluster: listen: 0.0.0.0:22122 hash: fnv1a_64 distribution: ketama timeout: 400 backlog: 65535 preconnect: true redis: true server_connections: 1 auto_eject_hosts: true server_retry_timeout: 60000 server_failure_limit: 3 servers: - 172.16.0.172:6546:1 redis01 - 172.16.0.172:6547:1 redis02
構成オプションの概要:
redis-cluster: この構成セグメントに名前を付けます。複数の構成セグメントが存在する可能性があります;
listen: 監視 IP とポートを設定;
hash: 特定のハッシュ関数、md5、crc16、crc32、finv1a_32、fnv1a_64、hsieh、murmur、jenkins などをサポート、10 種類以上、通常は fnv1a_64 を選択します。デフォルトも fnv1a_64 です;
書き換え: hash_tag 関数を使用して、キーの特定の部分に基づいてキーのハッシュ値を計算します。ハッシュタグはハッシュタグの先頭とハッシュタグの末尾の2文字で構成されており、ハッシュタグの先頭と末尾の間がキーのハッシュ値を計算する部分であり、計算結果は以下のようになります。サーバーを選択するために使用されます。例: hash_tag が「{}」と定義されている場合、「user:{user1}:ids」および「user:{user1}:tweets」のキー値を持つハッシュ値は「」に基づきます。 user1" であり、最終的には同じサーバーにマップされます。また、「user:user1:ids」はキー全体を使用してハッシュを計算します。ハッシュは別のサーバーにマッピングされる可能性があります。
配布: ハッシュ アルゴリズムを指定します。このハッシュ アルゴリズムは、上記のハッシュされたキーが複数のサーバーにどのように配布されるかを決定します。デフォルトは、「ケタマ」コンシステント ハッシュです。 ketama: ketama のコンシステント ハッシュ アルゴリズムは、サーバーに基づいてハッシュ リングを構築し、リング上のノードにハッシュ範囲を割り当てます。 ketama の利点は、単一ノードを追加または削除した後、クラスター全体でキャッシュされたキー値を最大限に再利用できることです。モジュラ: モジュラは非常にシンプルで、キー値のハッシュ値に基づいてモジュロを取得し、モジュロの結果に基づいて対応するサーバーを選択します。ランダム: ランダムとは、キー値のハッシュが何であっても、サーバーがキー値操作のターゲットとしてランダムに選択されることを意味します。
timeout: twemproxy のタイムアウトを設定します。タイムアウトが設定されている場合、タイムアウト後にサーバーから応答が受信されない場合、タイムアウト エラー メッセージ SERVER_ERROR 接続タイムアウトがクライアントに送信されます
Backlog: リスニングしている TCP バックログ (接続待機キュー) の長さ。デフォルトは 512 です。
preconnect: システムの起動時に twemproxy がすべての Redis との接続を確立するかどうかを指定します。デフォルトは false、ブール値です。
redis: この構成セクションをプロキシとして使用するかどうかを指定しますredis を追加せずに redis が true の場合、memcached クラスターのプロキシとして機能できます (これが、redis としての Twemproxy と memcached クラスター プロキシの唯一の違いです);
redis_auth: バックエンド Redis の場合認証がオンになっている場合、redis_auth の認証パスワードを指定する必要があります;
server_connections: twemproxy と各 Redis サーバー間の接続の数。デフォルトは 1 です。1 より大きい場合、ユーザー コマンドは異なる接続に送信されるため、コマンドが実際に実行される可能性があります。順序はユーザーが指定したものと一致しません (同時実行と同様);
auto_eject_hosts: ノードが応答できないときにノードを排出するかどうかデフォルトは true ですが、ノードが排出された後は、マシンの数が減少するため、マシンのハッシュ位置が変更されることに注意してください。これにより、いくつかのキーがヒットしなくなる可能性がありますが、プログラム接続が削除されない場合は、エラーが報告されます;
server_retry_timeout: サーバー接続の時間間隔をミリ秒単位で制御します。auto_eject_host が true に設定されている場合に有効になります。デフォルトは 30000 ミリ秒です。
server_failure_limit:Redis连续超时的次数,超过这个次数就视其为无法连接,如果auto_eject_hosts设置为true,那么此Redis会被移除;
servers:一个pool中的服务器的地址、端口和权重的列表,包括一个可选的服务器的名字,如果提供服务器的名字,将会使用它决定server的次序,从而提供对应的一致性hash的hash ring。否则,将使用server被定义的次序,可以通过两种字符串格式指定’host:port:weight’或者’host:port:weight name’。一般都是使用第二种别名的方式,这样当其中某个Redis节点出现问题时,可以直接添加一个新的Redis节点但服务器名字不要改变,这样twemproxy还是使用相同的服务器名称进行hash ring,所以其他数据节点的数据不会出现问题(只有挂点的机器数据丢失)。
PS:要严格按照Twemproxy配置文件的格式来,不然就会有语法错误;另外,在Twemproxy的配置文件中可以同时设置代理Redis集群或Memcached集群,只需要定义不同的配置段即可。
刚已经加好了配置文件,现在测试下配置文件:
[root@www twemproxy]# /etc/twemproxy/sbin/nutcracker -tnutcracker: configuration file 'conf/nutcracker.yml' syntax is ok
说明配置文件已经成功,现在开始运行nutcracker:
[root@www ~]# /etc/twemproxy/sbin/nutcracker -c /etc/twemproxy/conf/nutcracker.yml -p /var/run/nutcracker.pid -o /var/log/nutcracker.log -d选项说明: -h, –help #查看帮助文档,显示命令选项;-V, –version #查看nutcracker版本;-c, –conf-file=S #指定配置文件路径 (default: conf/nutcracker.yml);-p, –pid-file=S #指定进程pid文件路径,默认关闭 (default: off);-o, –output=S #设置日志输出路径,默认为标准错误输出 (default: stderr);-d, –daemonize #以守护进程运行;-t, –test-conf #测试配置脚本的正确性;-D, –describe-stats #打印状态描述;-v, –verbosity=N #设置日志级别 (default: 5, min: 0, max: 11);-s, –stats-port=N #设置状态监控端口,默认22222 (default: 22222);-a, –stats-addr=S #设置状态监控IP,默认0.0.0.0 (default: 0.0.0.0);-i, –stats-interval=N #设置状态聚合间隔 (default: 30000 msec);-m, –mbuf-size=N #设置mbuf块大小,以bytes单位 (default: 16384 bytes);
PS:一般在生产环境中,都是使用进程管理工具来进行twemproxy的启动管理,如supervisor或pm2工具,避免当进程挂掉的时候能够自动拉起进程。
[root@www ~]# ps aux | grep nutcrackerroot 20002 0.0 0.0 19312 916 ? Sl 18:48 0:00 /etc/twemproxy/sbin/nutcracker -c /etc/twemproxy/conf/nutcracker.yml -p /var/run/nutcracker.pid -o /var/log/nutcracker.log -d root 20006 0.0 0.0 103252 832 pts/0 S+ 18:48 0:00 grep nutcracker [root@www ~]# netstat -nplt | grep 22122tcp 0 0 0.0.0.0:22122 0.0.0.0:* LISTEN 20002/nutcracker
这里我们使用第一种方案在同一台主机上测试Twemproxy代理Redis集群,一个twemproxy和两个Redis节点(想添加更多的也可以)。Twemproxy就是用上面的配置了,下面只需要增加两个Redis节点。
在安装Redis之前,需要安装Redis的依赖程序tcl,如果不安装tcl在Redis执行make test的时候就会报错的哦。
[root@www ~]# yum install -y tcl[root@www ~]# wget https://github.com/antirez/redis/archive/3.2.0.tar.gz[root@www ~]# tar xvf 3.2.0.tar.gz -C /usr/local[root@www ~]# cd /usr/local/[root@www local]# mv redis-3.2.0 redis[root@www local]# cd redis[root@www redis]# make[root@www redis]# make test[root@www redis]# make install
[root@www ~]# mkdir /data/redis-6546[root@www ~]# mkdir /data/redis-6547[root@www ~]# cat /data/redis-6546/redis.confdaemonize yes pidfile /var/run/redis/redis-server.pid port 6546bind 0.0.0.0 loglevel notice logfile /var/log/redis/redis-6546.log [root@www ~]# cat /data/redis-6547/redis.confdaemonize yes pidfile /var/run/redis/redis-server.pid port 6547bind 0.0.0.0 loglevel notice logfile /var/log/redis/redis-6547.log
PS:简单提供两个Redis配置文件,如果开启了Redis认证,那么在twemproxy中也需要填写Redis密码。
[root@www ~]# /usr/local/redis/src/redis-server /data/redis-6546/redis.conf[root@www ~]# /usr/local/redis/src/redis-server /data/redis-6547/redis.conf[root@www ~]# ps aux | grep redisroot 23656 0.0 0.0 40204 3332 ? Ssl 20:14 0:00 redis-server 0.0.0.0:6546 root 24263 0.0 0.0 40204 3332 ? Ssl 20:16 0:00 redis-server 0.0.0.0:6547
首先twemproxy配置项中servers的主机要配置正确,然后连接Twemproxy的22122端口即可测试。
[root@www ~]# redis-cli -p 22122127.0.0.1:22122> set key vlaue OK 127.0.0.1:22122> get key"vlaue"127.0.0.1:22122> FLUSHALL Error: Server closed the connection 127.0.0.1:22122> quit
上面我们set一个key,然后通过twemproxy也可以获取到数据,一切正常。但是在twemproxy中使用flushall命令就不行了,不支持。
然后我们去找分别连接两个redis节点,看看数据是否出现在某一个节点上了,如果有,就说明twemproxy正常运行了。
[root@www ~]# redis-cli -p 6546127.0.0.1:6546> get key (nil) 127.0.0.1:6546>
由上面的结果我们可以看到,数据存储到6547节点上了。目前没有很好的办法明确知道某个key存储到某个后端节点了。
Twemproxy没有为启动提供脚本,只能通过命令行参数启动。所以,无法使用对twemproxy进行reload的操作,在生产环境中,一个应用无法reload(重载配置文件)是一个灾难。当你对twemproxy进行增删节点时如果直接使用restart的话势必会影响线上的业务。所以最好的办法还是reload,既然twemproxy没有提供,那么可以使用kill命令带一个信号,然后跟上twemproxy主进程的进行号即可。
kill -SIGHUP PID
注意,PID就是twemproxy master进程。
以上がRedis データシャーディングを実装する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。