redis-2.安装使用

·  阅读 122

安装

单机安装

  • docker install
docker run -d -p 6379:6379 --name redis-redisbloom redislabs/rebloom:latest
复制代码
  • manual install
yum -y install gcc automake autoconf libtool make vim
wget http://download.redis.io/releases/redis-5.0.5.tar.gz
tar zxf redis-5.0.5.tar.gz -C /soft/servers
cd /soft/servers/redis-5.0.5
make
make install
./utils/install_server.sh
复制代码

持久化配置

rdb的触发

  • 手动触发:

手动触发又分为save 命令阻塞触发 和bgsave 命令非阻塞触发。 save会触发前台阻塞。主要应用在 服务器 关机维护。 bgsave会触发fork()命令创建子进程异步写入磁盘。

  • 配置文件设置规则触发:

在conf配置文件中找到 SNAPSHOTTING 模块,

save 900 1
save 300 10
save 60 10000
# 这里的save表示的是触发bgsave命令,分别代表900秒操作数达到1次,300秒操作数达到10次,60秒操作数达到10000次触发bgsave。
复制代码

aof配置

conf文件中aof的配置:

appendonly no:aof为默认关闭状态,我们可以更改为appendonly yes开启。
appendfilename "appendonly.aof":默认文件名称。
appendfsync everysec:IO的级别默认为每秒发生一次flush。最多丢失一个buffer的数据。
appendfsync always:IO的级别为每次写都会发生flush。
appendfsync no:IO的级别为redis不主动flush,等待kernel的buffer满了自动flush。最多就是一个buffer的数据。
no-appendfsync-on-rewrite no:在发生rewrite或rdb的时候,不主动调用flush()争抢IO。数据敏感性高就开启为yes。
auto-aof-rewrite-percentage 100:最后一次重写后的体积大小所占比例100%,就会从64变为128。
auto-aof-rewrite-min-size 64mb:aof文件到达64m的时候,自动触发重写。
复制代码

集群

主从复制集群

主从复制搭建,可以在slave中使用replicaof 命令追随master。 master对外提供全量读写,slave对外提供读。 slave挂了可以直接重启,如果以前有追随master记录,那么就不会发生全量rdb。但是开启了aof就一定会发生全量rdb传输。

help replicaof
replicaof 172.17.0.4 6379
复制代码

redis-server /etc/redis/6379.conf --replicaof 172.17.0.4 6379 开启了aof,会导致172.17.0.4发送全量rdb给本机 redis-server /etc/redis/6379.conf --replicaof 172.17.0.4 6379 --appendonly yes

配置文件中配置主从复制:

  • replicaof

配置master的ip和端口

  • masterauth

访问master的密码

  • replica-serve-stale-data yes

在slave启动时,如果master中的数据量很大,在数据传输过程中,slave中的老的数据对外暴露,如果值为no需要同步完才能对外提供服务 。

  • replica-read-only yes

yes表示salve只读;no表示slave支持写入。

  • repl-diskless-sync no

如果为yes,表示直接走网络发送RDB。

  • repl-backlog-size 1mb

在master里会维护一个消息队列缓存临时写入的数据,salve如果挂掉后又启动了,master可能会有一个数据的增量,slave可以重新在master里面拿一份RDB恢复数据,也可以用RDB文件给master一个offset,从master队列中根据offset取出增量的数据恢复,这个配置的1mb就是设置这个队列的大小,如果master访问量大,把slave给出的offset对应的数据挤出,那么slave是无法恢复被挤出的数据的,这个时候就触发一个全量的RDB。

  • min-replicas-to-write 3

要求有三个健康的slave,master才能写成功。

  • min-replicas-max-lag 10

延迟小于min-replicas-max-lag秒的slave才认为是健康的slave

哨兵机制

  1. 找三台机器配置
port 26379
sentinel monitor mymaster 172.17.0.4 6379 2#表示quorum法定人数,3台机器需要2台
复制代码
  1. 三台机器启动哨兵

redis-server 26379.conf --sentinel

# 启动过程
# cat 26379.log
63:X 09 Jan 2021 15:58:54.620 # Sentinel ID is c39a7cb614dc1f38394455c4ff21c69efa9081cd
63:X 09 Jan 2021 15:58:54.620 # +monitor master mymaster 172.17.0.4 6379 quorum 2
63:X 09 Jan 2021 15:58:54.622 * +slave slave 172.17.0.5:6379 172.17.0.5 6379 @ mymaster 172.17.0.4 6379
63:X 09 Jan 2021 15:58:55.335 * +sentinel sentinel 7c23231eea5562ae404c6bc1fbdfe92e2fcf16aa 172.17.0.3 26379 @ mymaster 172.17.0.4 6379
63:X 09 Jan 2021 15:58:55.559 * +sentinel sentinel 1fd38d8910b6a7a5ecff59422f5a11bfb4266913 172.17.0.4 26379 @ mymaster 172.17.0.4 6379
63:X 09 Jan 2021 16:00:35.141 * +slave slave 172.17.0.3:6379 172.17.0.3 6379 @ mymaster 172.17.0.4 6379

# cat 26379.conf
port 26379
sentinel myid c39a7cb614dc1f38394455c4ff21c69efa9081cd
# Generated by CONFIG REWRITE
dir "/soft/servers/redis"
protected-mode no
sentinel deny-scripts-reconfig yes
sentinel monitor mymaster 172.17.0.4 6379 2
sentinel config-epoch mymaster 0
sentinel leader-epoch mymaster 0
sentinel known-replica mymaster 172.17.0.5 6379
sentinel known-replica mymaster 172.17.0.3 6379
sentinel known-sentinel mymaster 172.17.0.4 26379 1fd38d8910b6a7a5ecff59422f5a11bfb4266913
sentinel known-sentinel mymaster 172.17.0.3 26379 7c23231eea5562ae404c6bc1fbdfe92e2fcf16aa
sentinel current-epoch 0


# master宕机过程
# kill -9 $master_pid
# cat 26379.conf
[root@b2c2f37cb93b redis]# 68:X 09 Jan 2021 16:10:01.360 # +sdown master mymaster 172.17.0.4 6379
68:X 09 Jan 2021 16:10:01.414 # +odown master mymaster 172.17.0.4 6379 #quorum 2/2
68:X 09 Jan 2021 16:10:01.414 # +new-epoch 1
68:X 09 Jan 2021 16:10:01.414 # +try-failover master mymaster 172.17.0.4 6379
68:X 09 Jan 2021 16:10:01.415 # +vote-for-leader c39a7cb614dc1f38394455c4ff21c69efa9081cd 1
68:X 09 Jan 2021 16:10:01.420 # 1fd38d8910b6a7a5ecff59422f5a11bfb4266913 voted for c39a7cb614dc1f38394455c4ff21c69efa9081cd 1
68:X 09 Jan 2021 16:10:01.422 # 7c23231eea5562ae404c6bc1fbdfe92e2fcf16aa voted for c39a7cb614dc1f38394455c4ff21c69efa9081cd 1
68:X 09 Jan 2021 16:10:01.469 # +elected-leader master mymaster 172.17.0.4 6379
68:X 09 Jan 2021 16:10:01.469 # +failover-state-select-slave master mymaster 172.17.0.4 6379
68:X 09 Jan 2021 16:10:01.537 # +selected-slave slave 172.17.0.5:6379 172.17.0.5 6379 @ mymaster 172.17.0.4 6379
68:X 09 Jan 2021 16:10:01.537 * +failover-state-send-slaveof-noone slave 172.17.0.5:6379 172.17.0.5 6379 @ mymaster 172.17.0.4 6379
68:X 09 Jan 2021 16:10:01.601 * +failover-state-wait-promotion slave 172.17.0.5:6379 172.17.0.5 6379 @ mymaster 172.17.0.4 6379
68:X 09 Jan 2021 16:10:01.607 # +promoted-slave slave 172.17.0.5:6379 172.17.0.5 6379 @ mymaster 172.17.0.4 6379
68:X 09 Jan 2021 16:10:01.607 # +failover-state-reconf-slaves master mymaster 172.17.0.4 6379
68:X 09 Jan 2021 16:10:01.665 * +slave-reconf-sent slave 172.17.0.3:6379 172.17.0.3 6379 @ mymaster 172.17.0.4 6379
68:X 09 Jan 2021 16:10:02.579 # -odown master mymaster 172.17.0.4 6379
68:X 09 Jan 2021 16:10:02.636 * +slave-reconf-inprog slave 172.17.0.3:6379 172.17.0.3 6379 @ mymaster 172.17.0.4 6379
68:X 09 Jan 2021 16:10:02.636 * +slave-reconf-done slave 172.17.0.3:6379 172.17.0.3 6379 @ mymaster 172.17.0.4 6379
68:X 09 Jan 2021 16:10:02.712 # +failover-end master mymaster 172.17.0.4 6379
68:X 09 Jan 2021 16:10:02.712 # +switch-master mymaster 172.17.0.4 6379 172.17.0.5 6379
68:X 09 Jan 2021 16:10:02.713 * +slave slave 172.17.0.3:6379 172.17.0.3 6379 @ mymaster 172.17.0.5 6379
68:X 09 Jan 2021 16:10:02.713 * +slave slave 172.17.0.4:6379 172.17.0.4 6379 @ mymaster 172.17.0.5 6379
68:X 09 Jan 2021 16:10:32.737 # +sdown slave 172.17.0.4:6379 172.17.0.4 6379 @ mymaster 172.17.0.5 6379

# cat 26379.conf
port 26379
sentinel myid c39a7cb614dc1f38394455c4ff21c69efa9081cd
# Generated by CONFIG REWRITE
dir "/soft/servers/redis"
protected-mode no
sentinel deny-scripts-reconfig yes
sentinel monitor mymaster 172.17.0.5 6379 2
sentinel config-epoch mymaster 1
sentinel leader-epoch mymaster 1
sentinel known-replica mymaster 172.17.0.3 6379
sentinel known-replica mymaster 172.17.0.4 6379
sentinel known-sentinel mymaster 172.17.0.3 26379 7c23231eea5562ae404c6bc1fbdfe92e2fcf16aa
sentinel known-sentinel mymaster 172.17.0.4 26379 1fd38d8910b6a7a5ecff59422f5a11bfb4266913
sentinel current-epoch 1



127.0.0.1:6379> PSUBSCRIBE *
Reading messages... (press Ctrl-C to quit)
1) "psubscribe"
2) "*"
3) (integer) 1
1) "pmessage"
2) "*"
3) "__sentinel__:hello"
4) "172.17.0.3,26379,7c23231eea5562ae404c6bc1fbdfe92e2fcf16aa,1,mymaster,172.17.0.5,6379,1"
1) "pmessage"
2) "*"
3) "__sentinel__:hello"
4) "172.17.0.5,26379,c39a7cb614dc1f38394455c4ff21c69efa9081cd,1,mymaster,172.17.0.5,6379,1"
1) "pmessage"
复制代码

分区

cluster

  • 使用create-cluster脚本

./create-cluster satrt //启动节点 ./create-cluster create //创建集群 ./create-cluster stop //停止集群和节点 ./create-cluster clean //清理数据文件

# cd utils/create-cluster
# ./create-cluster start
# ./create-cluster create
# /soft/servers/redis/redis-cli --cluster info 127.0.0.1:30001
127.0.0.1:30001 (df9ce37f...) -> 0 keys | 5461 slots | 1 slaves.
127.0.0.1:30002 (f446380f...) -> 0 keys | 5462 slots | 1 slaves.
127.0.0.1:30003 (fb288d39...) -> 0 keys | 5461 slots | 1 slaves.
[OK] 0 keys in 3 masters.
0.00 keys per slot on average.
复制代码
  • 手动创建

手工启动的redis实例需要在配置文件中开启 cluster-enabled yes

redis-cli --cluster create 127.0.0.1:30001 127.0.0.1:30002 127.0.0.1:30003 127.0.0.1:30004 127.0.0.1:30005 127.0.0.1:30006 --cluster-replicas 1
redis-cli --cluster reshard 127.0.0.1:30001
redis-cli --cluster info 127.0.0.1:30001		#随便选一个节点的ip端口
redis-cli --cluster check 127.0.0.1:30001	
复制代码

twemproxy

git clone https://github.com/twitter/twemproxy.git
yum install automake   libtool -y
cd twemproxy
autoreconf -fvi
./configure
make
cd scripts/
cp nutcracker.init /etc/init.d/twemproxy
cd /etc/init.d/
chmod +x twemproxy  
mkdir  /etc/nutcracker/
cd  twemproxy /conf
cp ./*     /etc/nutcracker/
cd  twemproxy/src
cp nutcracker  /usr/bin
cd /etc/nutcracker
cp nutcracker.yml nutcracker.yml.back
vi nutcracker.yml
service twemproxy start
复制代码

nutcracker.yml

alpha:
  listen: 127.0.0.1:22121
  hash: fnv1a_64
  distribution: ketama
  auto_eject_hosts: true
  redis: true
  server_retry_timeout: 2000
  server_failure_limit: 1
  servers:
   - 127.0.0.1:6379:1
   - 127.0.0.1:6380:1
复制代码

客户端直接连接22121端口

predixy

mkdir predixy
cd predixy/
wget https://github.com/joyieldInc/predixy/releases/download/1.0.5/predixy-1.0.5-bin-amd64-linux.tar.gz
cd predixy/

vi predixy.conf
GENERAL模块:Bind 127.0.0.1:7617    			#设置对外暴露的统一接口
SERVERS模块:Include sentinel.conf				#引入哨兵配置文件

vi sentinel.conf
复制代码

sentinel.conf

SentinelServerPool {
    Databases 16
    Hash crc16
    HashTag "{}"
    Distribution modula
    MasterReadPriority 60
    StaticSlaveReadPriority 50
    DynamicSlaveReadPriority 50
    RefreshInterval 1
    ServerTimeout 1
    ServerFailureLimit 10
    ServerRetryTimeout 1
    KeepAlive 120
    Sentinels {
        + 127.0.0.1:26379								//三个哨兵的 IP+端口
        + 127.0.0.1:26380
        + 127.0.0.1:26381
    }
    Group ooxx {						//一套哨兵可以监控多套主从,一个Group为一套主从。
    }									//Client写入的数据会被打散分别存入ooxx主从的master和xxoo主从的master。
    Group xxoo {
    }
}
复制代码

配置哨兵

vi 26379.conf 
port 26379
sentinel monitor ooxx 127.0.0.1 36379 2			//第一套主从ooxx的master ID+ Port,组为ooxx
sentinel monitor xxoo 127.0.0.1 46379 2			//第二套主从xxoo的master ID+ Port	组为xxoo

vi  26380.conf
port 26380
sentinel monitor ooxx 127.0.0.1 36379 2
sentinel monitor xxoo 127.0.0.1 46379 2

vi  26381.conf
port 26381
sentinel monitor ooxx 127.0.0.1 36379 2
sentinel monitor xxoo 127.0.0.1 46379 2

#启动哨兵
redis-server 26379.conf --sentinel
redis-server 26380.conf --sentinel
redis-server 26381.conf --sentinel

# 建立四个个文件夹36379、36380、46379、46380,分别进去启动对应的redis

redis-server --port 36379
redis-server --port 46379

#开启两个从机,追随对应的主机
redis-server --port 36380 --replicaof 127.0.0.1 36379
redis-server --port 46380 --replicaof 127.0.0.1 46379

#进入代理predixy的根目录
./predixy ../conf/predixy.conf 

#客户端连接
redis-cli -p 7617
复制代码

附录

redis默认配置

bind 127.0.0.1
protected-mode yes
port 6379
tcp-backlog 511
timeout 0
tcp-keepalive 300
daemonize yes
supervised no
pidfile /var/run/redis_6379.pid
loglevel notice
logfile /var/log/redis_6379.log
databases 16
always-show-logo yes
save 900 1
save 300 10
save 60 10000
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename dump.rdb
dir /var/lib/redis/6379
replica-serve-stale-data yes
replica-read-only yes
repl-diskless-sync no
repl-diskless-sync-delay 5
repl-disable-tcp-nodelay no
replica-priority 100
lazyfree-lazy-eviction no
lazyfree-lazy-expire no
lazyfree-lazy-server-del no
replica-lazy-flush no
appendonly yes
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
aof-use-rdb-preamble yes
lua-time-limit 5000
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
stream-node-max-bytes 4096
stream-node-max-entries 100
activerehashing yes
client-output-buffer-limit normal 0 0 0
client-output-buffer-limit replica 256mb 64mb 60
client-output-buffer-limit pubsub 32mb 8mb 60
hz 10
dynamic-hz yes
aof-rewrite-incremental-fsync yes
rdb-save-incremental-fsync yes
复制代码

使用

五种数据结构

string

#查看k1的value类型
type k1
#面向字符串可以有计算类型,这里的int指的是k2的value的编码类型而不是type
object encoding k2
复制代码

字符串操作

help @string
set k1 value1 nx #nx表示无值的时候才执行成功
set k1 value1 xx #xx表示有值的时候才执行成功
append k1 "world" #在k1后面追加world

mset k3 value3 k4 value4 #含义为 more set,用来设置多个值
mget k1 k2 #获取两个值
msetnx k2 c k3 d #这个命令可以保证多笔操作是原子操作,类似于一个事务中

getrange k1 2 5 #获取k1某两个索引之间的字符串子串(支持正负索引)
setrange k1 3 xxx #从某个索引开始覆盖

strlen k1 #获取字符串长度

getset k1 v1new #设置新值并返回旧值(这样可以减少一次IO通信)
复制代码

数值操作

incrby k2 12
decr k2
decrby k2 22
incrbyfloat k2 0.5
复制代码

bitmap操作

# BITPOS key bit [start] [end] 返回位图中第一个值为 bit 的二进制位的位置。
127.0.0.1:6379> SETBIT bits 3 1    # 1000
(integer) 0
127.0.0.1:6379> BITPOS bits 0
(integer) 0
127.0.0.1:6379> BITPOS bits 1
(integer) 3
#位操作,与或非
setbit k1 1 1
setbit k1 7 1
get k1
setbit k2 1 1
setbit k2 6 1
#与操作 有0则0,全1为1
#01000000
bittop and andkey k1 k2
#或操作 有1则1,全0为0
#01000011
bittop or orkey k1 k2
复制代码

list

#可以用List类型实现一个栈:
lpush k1 a b c d e # 左边push
lpop k1 # e d c b a左边pop(后进先出)

#可以用List类型实现一个队列:
lpush k1 a b c d e # 左边push
rpop k1 a b c d e #右边pop(先进先出)

#获取List中某个范围之间的所有元素(支持负向索引)
LRANGE k1 0 -1 #获取整个List
复制代码

hash

hset sean name 'minato aqua'
hmset sean age 18 address hovelive

hget sean name
hget sean address
hmget sean name age
hkeys sean
hvals sean
hgetall sean

hincrbyfloat sean age 0.5
hincrbyfloat sean age -1
复制代码

set

#set特点:无序+去重
help @set
sadd k1 tom sean peter ooxx tom xxoo
smembers k1
srem k1 xxoo ooxx
smembers k1

sadd k2 1 2 3 4 5
sadd k3 4 5 6 7 8
sinter k2 k3

#插入到dest里头
sinterstore dest k2 k3

sunion k2 k3
#同上,存在rstore,并集
sdiff k2 k3
sdiff k3 k2

spop k1
复制代码

sortedset

#想让它们怎么排序?名称?大小?价格?
help @sorted_set
 
zadd k1 8 apple 2 banana 3 orange
#物理内存左小右大,不随命令发生变化
#查看
zrange k1 0 -1
#查看分值
zrange k1 0 -1 withscores
#取分值范围
zrangebyscore k1 3 8
#正向取
zrange k1 0 1
#反向取
zrevrange k1 0 1
#通过值取分值
zscore k1 apple
#取出排名
zrank k1 apple
#查看所有
zrange k1 0 -1 withscores
#增加
zincrby k1 2.5 banana
#实时根据修改更新排序
zrange k1 0 -1 withscores
#集合取并集
zadd k1 80 tom 60 sean 70 baby
zadd k2 60 tom 100 sean 40 yiming
zunionstore unkey 2 k1 k2
zrange unkey 0 -1 withscores
#设置权重
zunionstore unkey1 2 k1 k2 weights 1 0.5
#k1里面的不变,k2里面的乘0.5
zrange unkey1 0 -1 withscores
#取最大的
zunionstore unkey2 2 k1 k2 aggregate max
zrange unkey2 0 -1 withscores
复制代码

发布订阅

help @pubsub
PUBLISH test hello
SUBSCRIBE test
复制代码

pipeline

客户端和服务器通过网络进行连接。这个连接可以很快(loopback接口)或很慢(建立了一个多次跳转的网络连接)。无论网络延如何延时,数据包总是能从客户端到达服务器,并从服务器返回数据回复客户端。 这个时间被称之为 RTT (Round Trip Time - 往返时间). 当客户端需要在一个批处理中执行多次请求时很容易看到这是如何影响性能的(例如添加许多元素到同一个list,或者用很多Keys填充数据库)。例如,如果RTT时间是250毫秒(在一个很慢的连接下),即使服务器每秒能处理100k的请求数,我们每秒最多也只能处理4个请求。

一次请求/响应服务器能实现处理新的请求即使旧的请求还未被响应。这样就可以将多个命令发送到服务器,而不用等待回复,最后在一个步骤中读取该答复。

(printf "PING\r\nPING\r\nPING\r\n"; sleep 1) | nc localhost 6379
+PONG
+PONG
+PONG
复制代码

事务

MULTI 、 EXEC 、 DISCARD 和 WATCH 是 Redis 事务相关的命令。事务可以一次执行多个命令, 并且带有以下两个重要的保证:

  • 事务是一个单独的隔离操作:事务中的所有命令都会序列化、按顺序地执行。事务在执行的过程中,不会被其他客户端发送来的命令请求所打断。
  • 事务是一个原子操作:事务中的命令要么全部被执行,要么全部都不执行。

EXEC 命令负责触发并执行事务中的所有命令:

  • 如果客户端在使用 MULTI 开启了一个事务之后,却因为断线而没有成功执行 EXEC ,那么事务中的所有命令都不会被执行。
  • 另一方面,如果客户端成功在开启事务之后执行 EXEC ,那么事务中的所有命令都会被执行。

在事务中 watch 监控某个 key,如果发生改变,就不执行事务

image.png

> MULTI
OK
> INCR foo
QUEUED
> INCR bar
QUEUED
> EXEC
1) (integer) 1
2) (integer) 1
复制代码

redis的事务为什么不支持回滚?

  • Redis 命令只会因为错误的语法而失败(并且这些问题不能在入队时发现),或是命令用在了错误类型的键上面:这也就是说,从实用性的角度来说,失败的命令是由编程错误造成的,而这些错误应该在开发的过程中被发现,而不应该出现在生产环境中。
  • 因为不需要对回滚进行支持,所以 Redis 的内部可以保持简单且快速

RedisBloom模块 - 布隆过滤器

github.com/RedisBloom/…

redis-server --loadmodule /path/to/redisbloom.so

bf.add #添加元素
bf.exists #查询元素是否存在
bf.madd #一次添加多个元素
bf.mexists #一次查询多个元素是否存在
# 在 redis 中有两个值决定布隆过滤器的准确率:
#   error_rate:允许布隆过滤器的错误率,这个值越低过滤器的位数组的大小越大,占用空间也就越大。
#   initial_size:布隆过滤器可以储存的元素个数,当实际存储的元素个数超过这个值之后,过滤器的准确率会下降。
# redis 中有一个命令可以来设置这两个值:
bf.reserve test 0.01 100
# 第一个值是过滤器的名字。
# 第二个值为 error_rate 的值。
# 第三个值为 initial_size 的值。
复制代码

过期

redis> SET cache_page "www.google.com"
OK
redis> EXPIRE cache_page 30  # 设置过期时间为 30 秒
(integer) 1
redis> TTL cache_page    # 查看剩余生存时间
(integer) 23
redis> EXPIRE cache_page 30000   # 更新过期时间
(integer) 1
redis> TTL cache_page
(integer) 29996
复制代码
分类:
后端
标签: