Redis3.2.9/4.0.1集群部署配置优化

Redis3.2.9/4.0.1集群部署配置优化

参考文档

http://www.redis.cn/topics/cluster-spec.html

键分布模型

键空间被分割为 16384 槽(slot),事实上集群的最大节点数量是 16384 个。(然而建议最大节点数量设置在1000这个数量级上)

所有的主节点都负责 16384 个哈希槽中的一部分。当集群处于稳定状态时,集群中没有在执行重配置(reconfiguration)操作,每个哈希槽都只由一个节点进行处理(不过主节点可以有一个或多个从节点,可以在网络断线或节点失效时替换掉主节点)。

以下是用来把键映射到哈希槽的算法(下一段哈希标签例外就是按照这个规则):

HASH_SLOT = CRC16(key) mod 16384

其中,CRC16的定义如下:

名称:XMODEM(也可以称为 ZMODEM 或 CRC-16/ACORN)

输出长度:16 bit

多项数(poly):1021(即是 x16 + x12 + x5 + 1 )

初始化:0000

反射输入字节(Reflect Input byte):False

反射输入CRC(Reflect Output CRC):False

用于输出CRC的异或常量(Xor constant to output CRC):0000

该算法对于输入”123456789”的输出:31C3

CRC16的16位输出中的14位会被使用(这也是为什么上面的式子中有一个对 16384 取余的操作)。 在我们的测试中,CRC16能相当好地把不同的键均匀地分配到 16384 个槽中。

注意: 在本文档的附录A中有CRC16算法的实现。

Redis499问题根本原因是redis发生了阻塞,是linux系统环境(CPU/内存/IO)、Redis配置、客户端使用多方综合导致,由于大数据部门使用量巨大,需要持续优化验证。

redis优化相关

1,单个redis实例 内存控制在10GB以内,fork耗时每GB在20ms左右,10GB在200ms左右(latest_fork_usec:287905),需要配置maxmemory,最大内存的70%左右

2,降低fork操作频率,适度放宽rdb/aof自动触发时机(默认只开启rdb持久化且每分钟有1万key变更就触发rdb持久化)

3,repl-timeout默认60s,如果rdb(目前rdb文件压缩后有3G多,不压缩有10GB左右,默认开启压缩,目前量至少需要2-3分钟才能同步完成)60S内数据没有同步到从节点,主节点会认为从

节点故障并中断复制连接

4,客户端尽量避免使用高算法复杂度的命令,可以通过info commandstats查看

可能还有其他需要关注的点,后续了解后再补充

linux配置优化相关(只适用redis服务器)

1,关闭THP

临时

echo never > /sys/kernel/mm/transparent_hugepage/enabled

永久

/etc/rc.local

if test -f /sys/kernel/mm/redhat_transparent_hugepage/enabled; then

echo never > /sys/kernel/mm/redhat_transparent_hugepage/enabled

fi

2,内存分配策略

临时

echo 1 > /proc/sys/vm/overcommit_memory (默认0)

永久

echo "vm.overcommit_memory=1" >>/etc/sysctl.conf

3,交换分区策略

临时

echo 10 >  /proc/sys/vm/swappiness (默认60)

永久

echo "vm.swappiness=10"  >>/etc/sysctl.conf

4,分盘存储

单机多实例情况下,不同实例RDB/AOF文件分盘存储(2实例虚拟机最好挂载2块盘)

运营添加业务监控:应用方加入异常报警,发生阻塞时线上应用会最先感知到

运维部署CacheCloud监控集群状态,便于发现定位问题

补充资料

查看状态

redis-cli -c -p 7004 info persistence

redis-cli -c -p 7004 info replication

redis-cli -c -p 7004 info commandstats

redis-cli -c -p 7004 info stats

redis-cli -c -p 7004 --stat

阻塞问题汇总

https://redis.io/topics/latency

集群客户端

使用最多的时java客户端, Jedis 最近添加了对集群的支持, 详细请查看项目README中Jedis Cluster部分.

StackExchange.Redis 提供对 C# 的支持(并且包括大部分 .NET 下面的语言,比如: VB, F#等等)

thunk-redis 提供对 Node.js 和 io.js的支持。

Redis unstable 分支中的 redis-cli 程序实现了非常基本的集群支持, 可以使用命令 redis-cli -c 来启动。

redis-cli 对集群的支持是非常基本的, 所以它总是依靠 Redis 集群节点来将它转向(redirect)至正确的节点。一个真正的(serious)集群客户端应该做得比这更好: 它应该用缓存记录起哈希槽与节点地址之间的映射(map), 从而直接将命令发送到正确的节点上面。这种映射只会在集群的配置出现某些修改时变化, 比如说, 在一次故障转移(failover)之后, 或者系统管理员通过添加节点或移除节点来修改了集群的布局(layout)之后, 诸如此类。

CONFIG SET SAVE "900 1 300 10".

Redis 持久化

Redis 提供了不同级别的持久化方式:

RDB持久化方式能够在指定的时间间隔能对你的数据进行快照存储.

AOF持久化方式记录每次对服务器写的操作,当服务器重启的时候会重新执行这些命令来恢复原始的数据,AOF命令以redis协议追加保存每次写的操作到文件末尾.Redis还能对AOF文件进行后台重写,使得AOF文件的体积不至于过大.

如果你只希望你的数据在服务器运行的时候存在,你也可以不使用任何持久化方式.

你也可以同时开启两种持久化方式, 在这种情况下, 当redis重启的时候会优先载入AOF文件来恢复原始的数据,因为在通常情况下AOF文件保存的数据集要比RDB文件保存的数据集要完整.

最重要的事情是了解RDB和AOF持久化方式的不同,让我们以RDB持久化方式开始:

RDB的优点

RDB是一个非常紧凑的文件,它保存了某个时间点得数据集,非常适用于数据集的备份,比如你可以在每个小时报保存一下过去24小时内的数据,同时每天保存过去30天的数据,这样即使出了问题你也可以根据需求恢复到不同版本的数据集.

RDB是一个紧凑的单一文件,很方便传送到另一个远端数据中心或者亚马逊的S3(可能加密),非常适用于灾难恢复.

RDB在保存RDB文件时父进程唯一需要做的就是fork出一个子进程,接下来的工作全部由子进程来做,父进程不需要再做其他IO操作,所以RDB持久化方式可以最大化redis的性能.

与AOF相比,在恢复大的数据集的时候,RDB方式会更快一些.

RDB的缺点

如果你希望在redis意外停止工作(例如电源中断)的情况下丢失的数据最少的话,那么RDB不适合你.虽然你可以配置不同的save时间点(例如每隔5分钟并且对数据集有100个写的操作),是Redis要完整的保存整个数据集是一个比较繁重的工作,你通常会每隔5分钟或者更久做一次完整的保存,万一在Redis意外宕机,你可能会丢失几分钟的数据.

RDB 需要经常fork子进程来保存数据集到硬盘上,当数据集比较大的时候,fork的过程是非常耗时的,可能会导致Redis在一些毫秒级内不能响应客户端的请求.如果数据集巨大并且CPU性能不是很好的情况下,这种情况会持续1秒,AOF也需要fork,但是你可以调节重写日志文件的频率来提高数据集的耐久度.

AOF 优点

使用AOF 会让你的Redis更加耐久: 你可以使用不同的fsync策略:无fsync,每秒fsync,每次写的时候fsync.使用默认的每秒fsync策略,Redis的性能依然很好(fsync是由后台线程进行处理的,主线程会尽力处理客户端请求),一旦出现故障,你最多丢失1秒的数据.

AOF文件是一个只进行追加的日志文件,所以不需要写入seek,即使由于某些原因(磁盘空间已满,写的过程中宕机等等)未执行完整的写入命令,你也也可使用redis-check-aof工具修复这些问题.

Redis 可以在 AOF 文件体积变得过大时,自动地在后台对 AOF 进行重写: 重写后的新 AOF 文件包含了恢复当前数据集所需的最小命令集合。 整个重写操作是绝对安全的,因为 Redis 在创建新 AOF 文件的过程中,会继续将命令追加到现有的 AOF 文件里面,即使重写过程中发生停机,现有的 AOF 文件也不会丢失。 而一旦新 AOF 文件创建完毕,Redis 就会从旧 AOF 文件切换到新 AOF 文件,并开始对新 AOF 文件进行追加操作。

AOF 文件有序地保存了对数据库执行的所有写入操作, 这些写入操作以 Redis 协议的格式保存, 因此 AOF 文件的内容非常容易被人读懂, 对文件进行分析(parse)也很轻松。 导出(export) AOF 文件也非常简单: 举个例子, 如果你不小心执行了 FLUSHALL 命令, 但只要 AOF 文件未被重写, 那么只要停止服务器, 移除 AOF 文件末尾的 FLUSHALL 命令, 并重启 Redis , 就可以将数据集恢复到 FLUSHALL 执行之前的状态。

AOF 缺点

对于相同的数据集来说,AOF 文件的体积通常要大于 RDB 文件的体积。

根据所使用的 fsync 策略,AOF 的速度可能会慢于 RDB 。 在一般情况下, 每秒 fsync 的性能依然非常高, 而关闭 fsync 可以让 AOF 的速度和 RDB 一样快, 即使在高负荷之下也是如此。 不过在处理巨大的写入载入时,RDB 可以提供更有保证的最大延迟时间(latency)。

部署节点

echo never > /sys/kernel/mm/redhat_transparent_hugepage/enabled

echo "vm.overcommit_memory=1" >>/etc/sysctl.conf

echo "vm.swappiness=10"  >>/etc/sysctl.conf

yum -y install tcl-devel

wget http://download.redis.io/releases/redis-3.2.9.tar.gz

tar zxvf redis-3.2.9.tar.gz

cd redis-3.2.9

make

make test

make install

sh ./utils/install_server.sh

/data/redis/redis_7001.log

/data/redis/7001

Selected config:

Port          : 7001

Config file    : /etc/redis/7001.conf

Log file      : /data/redis/redis_7001.log

Data dir      : /data/redis/7001

Executable    : /usr/local/bin/redis-server

Cli Executable : /usr/local/bin/redis-cli

集群管理

wget https://cache.ruby-lang.org/pub/ruby/2.3/ruby-2.3.4.tar.gz

tar -xzvf ruby-2.3.4.tar.gz

cd ruby-2.3.4

./configure --disable-install-rdoc

make && make install

/usr/local/bin/ruby

/usr/local/bin/gem

gem sources --add https://ruby.taobao.org/ --remove https://rubygems.org/

gem install redis

[root@redisep69 ruby-2.3.4]# gem install redis

Fetching: redis-3.3.3.gem (100%)

Successfully installed redis-3.3.3

Parsing documentation for redis-3.3.3

Installing ri documentation for redis-3.3.3

Done installing documentation for redis after 1 seconds

1 gem installed

集群节点配置

[root@redisep69 etc]# cat /etc/redis/7001.conf20170821

bind 192.168.188.69

protected-mode no

port 7001

tcp-backlog 511

timeout 0

tcp-keepalive 300

daemonize yes

supervised no

pidfile /var/run/redis_7001.pid

loglevel notice

logfile /data/redis/redis_7001.log

databases 16

save 900 100

save 300 1000

save 60 10000

stop-writes-on-bgsave-error yes

rdbcompression yes

rdbchecksum yes

dbfilename dump.rdb

dir /data/redis/7001

slave-serve-stale-data yes

slave-read-only yes

repl-diskless-sync no

repl-diskless-sync-delay 5

repl-timeout 300

repl-disable-tcp-nodelay no

slave-priority 100

maxclients 40000

maxmemory 20gb

appendonly no

appendfilename "appendonly.aof"

appendfsync everysec

no-appendfsync-on-rewrite no

auto-aof-rewrite-percentage 100

auto-aof-rewrite-min-size 64mb

aof-load-truncated yes

lua-time-limit 5000

cluster-enabled yes

cluster-config-file nodes-7001.conf

cluster-node-timeout 10000

slowlog-log-slower-than 10000

slowlog-max-len 128

latency-monitor-threshold 0

notify-keyspace-events ""

hash-max-ziplist-entries 512

hash-max-ziplist-value 64

list-max-ziplist-size -2

list-compress-depth 0

set-max-intset-entries 512

zset-max-ziplist-entries 128

zset-max-ziplist-value 64

hll-sparse-max-bytes 3000

activerehashing yes

client-output-buffer-limit normal 0 0 0

client-output-buffer-limit slave 256mb 64mb 60

client-output-buffer-limit pubsub 32mb 8mb 60

hz 10

aof-rewrite-incremental-fsync yes

加入集群

[root@redisep69 bin]# redis-trib.rb create --replicas 1 192.168.188.69:7001 192.168.188.70:7002 192.168.188.71:7003 192.168.188.72:7004 192.168.188.73:7005  192.168.188.74:7006

>>> Creating cluster

>>> Performing hash slots allocation on 6 nodes...

Using 3 masters:

192.168.188.69:7001

192.168.188.70:7002

192.168.188.71:7003

Adding replica 192.168.188.72:7004 to 192.168.188.69:7001

Adding replica 192.168.188.73:7005 to 192.168.188.70:7002

Adding replica 192.168.188.74:7006 to 192.168.188.71:7003

M: b44e8f7e4505180f9969ecd5fee1b15f5dc3e045 192.168.188.69:7001

slots:0-5460 (5461 slots) master

M: aec4598d4905792ec9e5d8ab7ca403d250a2e89f 192.168.188.70:7002

slots:5461-10922 (5462 slots) master

M: d3e940f440dc5b33969575924bcc416e4658cd0b 192.168.188.71:7003

slots:10923-16383 (5461 slots) master

S: 24df5294bab6cce79fb1e0a134a4f8f761f30006 192.168.188.72:7004

replicates b44e8f7e4505180f9969ecd5fee1b15f5dc3e045

S: e9fe9a686aacb76d16b28460ec17f3f79098dc22 192.168.188.73:7005

replicates aec4598d4905792ec9e5d8ab7ca403d250a2e89f

S: 57015121d70c9f89b01cca162a25397f27ba3171 192.168.188.74:7006

replicates d3e940f440dc5b33969575924bcc416e4658cd0b

Can I set the above configuration? (type 'yes' to accept): yes

>>> Nodes configuration updated

>>> Assign a different config epoch to each node

>>> Sending CLUSTER MEET messages to join the cluster

Waiting for the cluster to join.....

>>> Performing Cluster Check (using node 192.168.188.69:7001)

M: b44e8f7e4505180f9969ecd5fee1b15f5dc3e045 192.168.188.69:7001

slots:0-5460 (5461 slots) master

1 additional replica(s)

M: aec4598d4905792ec9e5d8ab7ca403d250a2e89f 192.168.188.70:7002

slots:5461-10922 (5462 slots) master

1 additional replica(s)

S: 24df5294bab6cce79fb1e0a134a4f8f761f30006 192.168.188.72:7004

slots: (0 slots) slave

replicates b44e8f7e4505180f9969ecd5fee1b15f5dc3e045

S: e9fe9a686aacb76d16b28460ec17f3f79098dc22 192.168.188.73:7005

slots: (0 slots) slave

replicates aec4598d4905792ec9e5d8ab7ca403d250a2e89f

S: 57015121d70c9f89b01cca162a25397f27ba3171 192.168.188.74:7006

slots: (0 slots) slave

replicates d3e940f440dc5b33969575924bcc416e4658cd0b

M: d3e940f440dc5b33969575924bcc416e4658cd0b 192.168.188.71:7003

slots:10923-16383 (5461 slots) master

1 additional replica(s)

[OK] All nodes agree about slots configuration.

>>> Check for open slots...

>>> Check slots coverage...

[OK] All 16384 slots covered.

保存节点配置到硬盘(默认会保存)

[root@redisep69 bin]# redis-cli -c -h 192.168.188.69 -p 7001

192.168.188.69:7001> CLUSTER SAVECONFIG

OK

192.168.188.69:7001>

压力测试

[root@redisep69 etc]# redis-benchmark -d 100  -n 2000000 -t get,set  -q  -h 192.168.188.69 -p 7001

SET: 120685.49 requests per second

GET: 152753.38 requests per second

[root@redisep69 etc]# redis-benchmark -d 10  -n 2000000 -t get,set  -q  -h 192.168.188.69 -p 7001

SET: 148754.19 requests per second

GET: 126887.45 requests per second

[root@redisep69 etc]# redis-benchmark -d 1  -n 2000000 -t get,set  -q  -h 192.168.188.69 -p 7001

SET: 141522.78 requests per second

GET: 158516.30 requests per second

[root@redisep71 ~]# redis-benchmark -d 100  -n 2000000 -t get,set  -q  -h 192.168.188.71 -p 7003

SET: 176928.52 requests per second

GET: 170198.28 requests per second

三节点集群注意事项

REDIS3节点集群默认会有一组主从在同一虚拟机上,需要手工调整,架构主-从为7001-7006  7002-7004  7003-7005,以下是调整主从例子。

[root@redis-108 ~]# redis-cli -c -h 172.17.6.110 -p 7006

172.17.6.110:7006> CLUSTER REPLICATE 560eca92df8080db9e0b3d8cf65ac1ed00c30dd0

OK

172.17.6.110:7006> exit

[root@redis-108 ~]# redis-cli -c -h 172.17.6.109 -p 7005

172.17.6.109:7005> CLUSTER REPLICATE 33d3ee604bc6136283038db12967c0dfb09e48a1

OK

172.17.6.109:7005> CLUSTER SAVECONFIG

OK

添加zabbix监控方法

zabbix添加redis模版方法                                                                                          

第一步                                                                                                          

 vim /usr/local/zabbix/etc/zabbix_agentd.conf

UserParameter=redis.discovery,/usr/local/zabbix/etc/redis_port.sh

UserParameter=redis_stats[*],redis-cli -h 172.17.6.108 -a redis_passwd -p $1 info|grep $2|cut -d : -f2

第二步

visudo

Defaults:zabbix  !requiretty

zabbix ALL=(root)  NOPASSWD:/bin/netstat

具体sh脚本如下

cat /usr/local/zabbix/etc/redis_port.sh

#!/bin/bash

#Fucation:mysql low-level discovery

#Script_name redis_low_discovery.sh

redis() {

port=($(sudo netstat -tpln | awk -F "[ :]+" '/redis/ && /0.0.0.0/ {print $5}'))

printf '{\n'

printf '\t"data":[\n'

for key in ${!port[@]}

do

if [[ "${#port[@]}" -gt 1 && "${key}" -ne "$((${#port[@]}-1))" ]];then

socket=`ps aux|grep ${port[${key}]}|grep -v grep|awk -F '=' '{print $10}'|cut -d ' ' -f 1`

printf '\t {\n'

printf "\t\t\t\"{#REDISPORT}\":\"${port[${key}]}\"},\n"

else [[ "${key}" -eq "((${#port[@]}-1))" ]]

socket=`ps aux|grep ${port[${key}]}|grep -v grep|awk -F '=' '{print $10}'|cut -d ' ' -f 1`

printf '\t {\n'

printf "\t\t\t\"{#REDISPORT}\":\"${port[${key}]}\"\n\t }\n"

fi

done

printf '\t ]\n'

printf '}\n'

}

redis  $1

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,547评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,399评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,428评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,599评论 1 274
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,612评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,577评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,941评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,603评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,852评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,605评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,693评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,375评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,955评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,936评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,172评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,970评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,414评论 2 342

推荐阅读更多精彩内容