Redis

linuxredis约 3324 字大约 11 分钟

常用类型和操作

认证登录

客户端工具redis-di登录

redis-cli
redis-cli -h redisd ip
redis-cli -h xxx -p xxx

# redis的认证
>auth password

redis-cli -a password

数据类型

常见的有字符串、列表、集合、等

字符串

›set name aaa

›keys *

>get name

>set name bbb

> del name

#增加key并赋值 #混示所有的key #获取key的佶 #重新绘key赋佶 #别除key

命令不区分大小写:>GET name

key区分大小写:>get Name

列表

127.0.0.1:6379> rpush name aaa  # rpush 依次在右边添加,lpush反之
(integer) 1
127.0.0.1:6379> rpush name bbb
(integer) 2
127.0.0.1:6379> rpush name vvv
(integer) 3
127.0.0.1:6379> rpush name ccc
(integer) 4
127.0.0.1:6379> get name
(error) WRONGTYPE Operation against a key holding the wrong kind of value
127.0.0.1:6379> scan 0
1) "0"
2) 1) "name"
127.0.0.1:6379> llen name
(integer) 4
127.0.0.1:6379> lrange name 0 4  # 列表需要使用lrange查看
1) "aaa"
2) "bbb"
3) "vvv"
4) "ccc"

# 删除第三个值
127.0.0.1:6379> lrem name 3 vvv
(integer) 1
127.0.0.1:6379> lrange name 0 4
1) "aaa"
2) "bbb"
3) "ccc"

# 弹出
lpop 左弹出
rpop 右弹出

集合


127.0.0.1:6379> sadd set s1
(integer) 1
127.0.0.1:6379> SMEMBERS set  # 列出集合的元素
1) "s1"
127.0.0.1:6379> sadd set s2
(integer) 1
127.0.0.1:6379> SMEMBERS set
1) "s1"
2) "s2"
127.0.0.1:6379> srem set s1  # 删除
(integer) 1
127.0.0.1:6379> SMEMBERS set
1) "s2"
127.0.0.1:6379>

spop 随机删除1个

hash哈希

127.0.0.1:6379> hset hash name zhangsan
(integer) 1
127.0.0.1:6379> hset hash age 18
(integer) 1
127.0.0.1:6379> hgetall hash # 获取全部值
1) "name"
2) "zhangsan"
3) "age"
4) "18"
127.0.0.1:6379> hget hash name # 获取单个值
"zhangsan"

# 删除

127.0.0.1:6379> hdel hash name
(integer) 1
127.0.0.1:6379> hgetall hash
1) "age"
2) "18"
127.0.0.1:6379> del hash
(integer) 1
127.0.0.1:6379> hgetall hash
(empty array)
127.0.0.1:6379>

发布和订阅

切库&运维命令

redis 有 0~15 共16个数据库,默认登录的为 0,不同的数据库,数据相互之前是独立的

127.0.0.1:6379> select 1
OK
127.0.0.1:6379[1]> select 16
(error) ERR DB index is out of range
127.0.0.1:6379[1]> select 0
OK
127.0.0.1:6379>

运维命令

> RANDOMKEY #随机获取一个key

> KEYS * #查看所有key,注意阻寨,如果key量特别大时候,容易卡死阻塞,上千万上百万时候容易阻塞 #建议使用,每次获取11个key,可以循环获取,直到获取所有key

> SCAN O #从编号0开始,中间会有一个编号提示(类似索引编号),按编号提示依次循环获取,直到编号为0即表示获取完所有的key

查看当前状态

> root@c93f2576f844:/data# redis-cli -a 123456 --stat

Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
------- data ------ --------------------- load -------------------- - child -
keys       mem      clients blocked requests            connections
0          907.06K  2       0       139 (+0)            18
0          907.06K  2       0       140 (+1)            18
0          907.06K  2       0       141 (+1)            18

DB操作监控

root@c93f2576f844:/data# redis-cli -a 123qweASD monitor
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
OK
1715600382.635851 [0 127.0.0.1:55854] "auth" "(redacted)"
1715600402.673287 [0 127.0.0.1:55854] "set" "monitor" "test"
1715600419.683035 [0 127.0.0.1:55854] "del" "monitor"
1715600424.181185 [0 127.0.0.1:55854] "scan" "0"
1715600426.952836 [0 127.0.0.1:55854] "get" "1"
1715600430.453308 [0 127.0.0.1:55854] "get" "name"

redis info查询

root@c93f2576f844:/data# redis-cli -a 123456 info # 查看所有
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
# Server
redis_version:6.2.6
redis_git_sha1:00000000
redis_git_dirty:0

root@c93f2576f844:/data# redis-cli -a 123456 info cpu # 查看某一个
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
# CPU
used_cpu_sys:14.208219
used_cpu_user:12.923262

配置动态更新

无需重启,修改配置并生效

127.0.0.1:6379> config get requirepass
1) "requirepass"
2) "123xxxxxx"
127.0.0.1:6379> config set requirepass 123456
OK
127.0.0.1:6379> config rewrite   # 写入配置文件 避免服务重启,配置丢失
(error) ERR Rewriting config file: Permission denied  
# 出现这个错误,需要对redis.conf赋权 chown USRE:USER redis.conf


# 测试一下

root@c93f2576f844:/data# redis-cli -a 123xxxx info cpu
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
AUTH failed: WRONGPASS invalid username-password pair or user is disabled.
root@c93f2576f844:/data# redis-cli -a 123456 info cpu
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
# CPU
used_cpu_sys:7.469806
used_cpu_user:6.857815
used_cpu_sys_children:0.012113
used_cpu_user_children:0.002291
used_cpu_sys_main_thread:7.467573
used_cpu_user_main_thread:6.857429
root@c93f2576f844:/data#

注意

所有配置操作结束,记得config rewrite

多用户管理

redis6 默认已有用户名,默认为default(超级用户)

127.0.0.1:6379> acl list # 列出所有用户
1) "user default on #8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92 ~* &* +@all"

127.0.0.1:6379> acl getuser default # 查看某个用户
 1) "flags"
 2) 1) "on"
    2) "allkeys"
    3) "allchannels"
    4) "allcommands"
 3) "passwords"
 4) 1) "8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92"
 5) "commands"
 6) "+@all"
 7) "keys"
 8) 1) "*"
 9) "channels"
10) 1) "*"

权限查看

127.0.0.1:6379> acl cat  # 查看 权限列表
 1) "keyspace"
 2) "read"
 3) "write"
 4) "set"
 5) "sortedset"
 6) "list"
 7) "hash"
 8) "string"
 9) "bitmap"
10) "hyperloglog"
11) "geo"
12) "stream"
13) "pubsub"
14) "admin"
15) "fast"
16) "slow"
17) "blocking"
18) "dangerous"
19) "connection"
20) "transaction"
21) "scripting"

创建用户


#创建test用户,密码:testpwd 赋给get命令的权限,只对name开头的有get权限 
>ACL SETUSER test on testpwd name* +get

#给test用户增加read权限,设置只对name开头的key有read权限
›ACL SETUSER test on testpwd name* + @read

 #查看test用户的相关信息
›ACL getuser test

#对所有key都有get权限
>ACL SETUSER t1 on >t1pwd ~* +get
#对所有key都有read权限
>ACL SETUSER t1 on >t1pwd ~* +@read

>ACL Getuser t1

# 删除用户
>ACL DELUSRE t1

常见赋权

# 创建用户赋给所有权限:
> ACL SETUSER testl on >testipwd ~* +@all #用户名:test1密码:testlpwd 
> ACL GETUSER test1

# 去除config命令后的所有权限
> ACL SETUSER test2 on >test2pwd ~* +@all -config
> ACL GETUSER test2

# 创建一个用户,只给info和momitoy命令权限
>ACL SETUSER monitor on >monitorpwd ~* +info +monitor 

慢日志&key有效期

系统慢常见外题:

  1. 内存使用情况
  2. CPU负载
  3. 磁盘空间
  4. 慢日志
127.0.0.1:6379> CONFIG GET slow*
1) "slowlog-max-len"
2) "128"
3) "slowlog-log-slower-than"
4) "10000"
127.0.0.1:6379>

# 模拟慢日志,调整时间 slowlog-log-slower-than
config set slowlog-log-slower-than 1000

模拟大量key插入

for i in $(seq -w 100000);do redis-cli -a 123456 set name$(i) test$(i); done 2>/dev/null

慢日志查询

>SLOWLOG get  #默认获取最近10条
>SLOWLOG get 5 #获取5条
>SLOWLOG len   #慢日志量,查看慢日志的条数 
>SLOWLOG reset #清空慢日志


#产生慢日志的命令,一般是当数据量太多时候,运行keys *命令会比较慢

127.0.0.1:6379> SLOWLOG get
1) 1) (integer) 2 #慢日志的id,从0开始,第2个id
   2) (integer) 1715676722 #时间戳,慢日志产生的时间点,可以通过 date -d @1668215297 获取慢日志产生的时间
   3) (integer) 3143  #慢日志运行的时间3毫秒
   4) 1) "keys"
      2) "*"
   5) "127.0.0.1:55966"
   6) ""

有效期

127.0.0.1:6379> set exk test ex 10 # 10秒有效
OK
127.0.0.1:6379> get exk
"test"
127.0.0.1:6379> ttl exk
(integer) 4
127.0.0.1:6379> ttl exk
(integer) 2
127.0.0.1:6379> ttl exk # 失效
(integer) -2
127.0.0.1:6379> set name zz
OK
127.0.0.1:6379> get name
"zz"
127.0.0.1:6379> ttl name # -1 永久有效
(integer) -1
127.0.0.1:6379> EXPIRE name 22  # 给已存在的key 设置有效时间
(integer) 1
127.0.0.1:6379> ttl name
(integer) 19
127.0.0.1:6379> ttl name
(integer) 17```

持久化

RDB

RDB即RedisDB的缩写,即将整个Redis内存数据持久化到一个文件。

127.0.0.1:6379> save # 阻塞保存
OK
127.0.0.1:6379> bgsave # 后台保存
Background saving started
127.0.0.1:6379>

#
root@c93f2576f844:/data# ls  # 保存后,会多出个dump.rdb文件
access.log  appendonly.aof  dump.rdb  s.sh
root@c93f2576f844:/data#

另外一种方式就是配置文件,Redis默认开启。

 save 900 1  //900s有一个key被修改时保存
 save 300 10  //300s内有10个key被修改时保存
 save 60 10000 //60s内有10000个key被修改时保存

RBD的优点是,全量数据二进制文件,数据恢复快。 缺点是,可能会丢数据。

AOF

将redis中每一步对数据修改的操作记录(日志)append到相应的文件中

配置文件

appendonly yes
# The name of the append only file (default: "appendonly.aof")
appendfilename "appendonly.aof"


# 查看配置
127.0.0.1:6379> CONFIG GET appen*
1) "appendonly"
2) "yes"
3) "appendfilename"
4) "appendonly.aof"
5) "appendfsync"
6) "everysec"

# 可通过config set 更改配置

为了降低IO消耗,AOF写文件时,会先将数据写到缓冲区,然后再把缓冲区的内容 flush 到磁盘,这个过程叫做 fsync。

频率有三种:

appendfsync always //每次写操作都flush,影响性能 appendfsync everysec //每秒flush appendfsync no //消极等待OS刷新(一般30s),可能丢失数据

重写

当AOF文件增大到一定程度,我们可以对他进行重写,重写AOF文件可以减小AOF文件的大小,数据不会减少

127.0.0.1:6379> CONFIG GET *aof*
 1) "aof-rewrite-incremental-fsync"
 2) "yes"
 3) "aof-load-truncated"
 4) "yes"
 5) "aof-use-rdb-preamble"
 6) "no"
 7) "aof_rewrite_cpulist"
 8) ""
 9) "auto-aof-rewrite-percentage"  # 达到100增量的时候,触发AOF重写
10) "100"
11) "auto-aof-rewrite-min-size" # > 64M ,触发重写
12) "67108864"
13) "replicaof"

混合模式

bgrewirteof(background+rewrite+aof),可以解决,文件过大的问题,但对历史命令的合并是非常耗费性能的,尤其是数据量非的情况下。因此,4.0后,出现混合模式。即执行bgrewirteof之后,将当前数据全量以RDB的方式写入appendonly文件的前半部分,之后的命令再以 append 的方式进行追加。

配置文件

aof-use-rdb-preamble yes

触发条件

auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb

bigkey

root@2318c3d768a7:/data# redis-cli -a 123qweASD --bigkeys
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.

# Scanning the entire keyspace to find biggest keys as well as
# average sizes per key type.  You can use -i 0.1 to sleep 0.1 sec
# per 100 SCAN commands (not usually needed).

[00.00%] Biggest string found so far '"name"' with 3 bytes

-------- summary -------

Sampled 1 keys in the keyspace!
Total key length in bytes is 4 (avg len 4.00)

Biggest string found '"name"' has 3 bytes

1 strings with 3 bytes (100.00% of keys, avg size 3.00)
0 lists with 0 items (00.00% of keys, avg size 0.00)
0 hashs with 0 fields (00.00% of keys, avg size 0.00)
0 streams with 0 entries (00.00% of keys, avg size 0.00)
0 sets with 0 members (00.00% of keys, avg size 0.00)
0 zsets with 0 members (00.00% of keys, avg size 0.00)
root@2318c3d768a7:/data#

主从

从redis需要增加下面这两项:

slave of 192.168.27.128 6379 #指定主redis的ip和端口 
masterauth "password" # #指定主redis的密码

角色查看

127.0.0.1:6379> info   # 通过info命令可查看出,当前的节点是什么角色等信息
...
...
Replication
role: slave
master_host: 192.168.27.128 master_port: 6379
master_link_status:up
master_last. _io_seconds_ago: 6 master_sync_in_progress:0
...

哨兵

Redis提供Sentinel工具实现主从自动切换,实现redis的高可用

redis-sentinel /etc/sentinel.conf

主挂掉后,从库自动提升为主库,主生恢复后,自动转为从库

要求主从都需要设置masterauth 连接主redis的密码

因为是高可用模式,主也有可能宕机,当它宿机后,即使再恢复后也是作为从角色,为了防止作为从角色时候, 连接主时候认证不了,需要提前加上连接主服务器的认证密码

为了防止哨兵的单节点故障,一般哨兵也做成高可用形式,即多个哨兵同时监控redis的状态,当其中一个哨兵故障时候,其他哨兵也能继续监控。

为了方便哨兵的选举,一般哨兵也是设置成奇数个。一般3个哨兵就没问题。

注意:一般哨兵的部署尽量不要和redis部署在同一台,防止这一台机器挂了后,redis和哨兵同时挂掉,哨兵起不到哨兵的作用了。当然多台机器, 多个哨兵时候也不影响,一台哨兵挂了,还有其它哨兵。

配置哨兵

sentinel.conf

bind 0.0.0.0
daemonize yes
port 26379 #服务端口
dir "/tmp"
logfile "sentinel.log"
sentinel monitor testmaster 192.168.27.128 6379 2 # master地址,2代表至少2个哨兵认为有问题,才进行切换
sentinel auth-pass testmaster password 
sentinel down-after-milliseconds testmaster 5000  # 5s未响应,则认为故障
sentinel failover-timeout testmaster 20000 # 20秒内,完成切换操作。

集群

分片存储,提高redis吞吐量。建议最少三主三从

主节点

redis-cli -a password --cluster create 192.168.x.x:7000 192.168.x.x:7001 192.168.x.x:7002

查看集群状态

> # redis-cli -a password -p 7000 cluster info

cluster_state:ok
cluster_slots_assigned: 16384
cluster_slots_ok: 16384
cluster_slots_pfail:0
cluster_slots_fail:0
cluster _known_nodes: 3
cluster_size: 3
cluster_current _epoch: 3
cluster_my_epoch: 1
cluster_stats_messages_ping_sent:32
cluster_stats_messages_pong_sent:34 
cluster_stats_messages_sent: 66
cluster_stats_messages_ping_received: 32
cluster_stats_messages_pong_received: 32 
cluster_stats_messages_meet_received: 2
cluster_stats_messages_received: 66


> # redis-cli -a password -p 7000 cluster nodes
查看集群节点信息

写入数据

# 集群操作需要加-c参数
redis-cli -p 7000 -a password #不加-C参数,表示不是以集群方式写入,无法写入 
redis-cli -p 7000 -a password -c #增加-C参数,表示是以集群方式写入,可以写入

从节点

redis-cli -a password --cluster add-node --cluster-slave --cluster-master-id 7001的master-id 192.168.x.x:8002 192.168.x.x.:7001

注意

命令中后面两个ip顺序不能颠倒,分别对应的一组主从,ip顺序为:从redis的ip:从端口 主redis的ip:主端口

手动将原主库提升为主库,可用命令 CLUSTER FAILOVER

节点增

使用add-node命令新增一个主节点

新增集群主节点

redis-cli -a password --cluster add-node 新节点IP:端口 已存在节点IP:端口(任意节点均可)

新增集群从节点

redis-cli -a password --cluster add-node --cluster-slave --cluster-master-id [MASTER ID] 新节点IP:端口 主节点IP:端口

分配 slot 槽。找到集群中的任意一个主节点,对其进行重新分片工作

redis-cli -a password --cluster reshard 已存在节点IP:端口

节点减

从库可以直接删除

redis-cli -a password --cluster del-node 对应主库的ip:端口 从库的id

主库的删除,需要做数据的迁移。使用槽位分配即可。

redis-cli -a password --cluster reshard 已存在节点IP:端口

删除master节点

redis-cli -a password --cluster del-node 对应主库的ip:端口 主库的id