百科:
Redis - 维基百科
推荐:
Redis 教程 - 菜鸟
请习惯查看官网
可视化工具 RedisInsight RedisInsight 是 Redis 官网可视化工具,前身为 Redis Desktop Manager。
AnotherRedisDesktopManager https://github.com/qishibo/AnotherRedisDesktopManager
官方 https://redis.io/
https://github.com/redis/redis
官方命令手册: https://redis.io/docs/latest/commands/
下载与安装 Linux 请从GitHub下载源码编译安装:
检查 1 2 3 4 5 6 7 8 9 10 11 12 13 find / | grep redis.conf find / | grep .*redis.* gcc --version make --version yum install gcc yum install make firewall-cmd --state systemctl start firewalld systemctl stop firewalld systemctl enable firewalld systemctl disable firewalld
安装 1 2 3 4 5 6 7 8 9 10 11 mkdir -p /opt/local/redis/log mkdir -p /opt/local/redis/pid mkdir -p /opt/local/redis/cluster cd /opt/local tar -zxvf redis-7.4.0.tar.gz cd /opt/local/redis-7.4.0 make distclean make make PREFIX=/opt/local/redis install make uninstall
为了让reids命令可以在任何位置执行,需配置环境变量 ,参考:** 环境变量持久化 **
1 2 3 echo "export PATH=/opt/local/redis/bin:$PATH" >> /etc/profile source /etc/profile vim /etc/profile
节点配置文件 阿里云Redis支持的参数及说明: https://help.aliyun.com/zh/redis/user-guide/supported-parameters
从解压目录复制一份配置文件:cp /opt/local/redis-7.4.0/redis.conf /opt/local/redis/redis.conf
创建 aclfile。Redis 6之后,requirepass 仅为default用户设置密码,而且启用 ACL 会使它失效。
1 2 echo "user default on ~* &* +@all >123456789" >> /opt/local/redis/users.aclecho "user worker on ~* &* +@all >123456789" > /opt/local/redis/users.acl
新建master节点配置文件 vim /opt/local/redis/redis_6379.conf
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 include /opt/local/redis/redis.conf bind * -::* protected-mode no port 6379 tcp-backlog 511 timeout 0 tcp-keepalive 300 daemonize yes pidfile /opt/local/redis/pid/redis_6379.pid loglevel notice logfile "/opt/local/redis/log/redis_6379.log" databases 16 aclfile /opt/local/redis/users.acl requirepass 123456789 maxclients 10000 maxmemory 104857600 maxmemory-policy noeviction maxmemory-samples 5 replica-ignore-maxmemory yes active-expire-effort 1 save 3600 1 300 100 60 10000 stop-writes-on-bgsave-error yes rdbcompression yes rdbchecksum yes dbfilename dump_6379.rdb dir /opt/local/redis/ appendonly yes appendfilename "appendonly_6379.aof" appenddirname "appendonlydir_6379" appendfsync everysec no-appendfsync-on-rewrite no auto-aof-rewrite-percentage 100 auto-aof-rewrite-min-size 64mb masterauth 123456789 masteruser worker replica-serve-stale-data yes replica-read-only yes repl-diskless-sync yes repl-diskless-sync-delay 5 repl-diskless-sync-max-replicas 0 repl-diskless-load disabled repl-ping-replica-period 10 repl-timeout 60 repl-disable-tcp-nodelay no replica-priority 100 cluster-config-file /opt/local/redis/cluster/nodes-6379.conf cluster-node-timeout 15000 cluster-require-full-coverage yes
新建slave节点配置文件 vim /opt/local/redis/redis_6380.conf
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 include /opt/local/redis/redis_6379.conf port 6380 requirepass 123456789 pidfile /opt/local/redis/pid/redis_6380.pid logfile "/opt/local/redis/log/redis_6380.log" dbfilename dump_6380.rdb appendfilename "appendonly_6380.aof" appenddirname "appendonlydir_6380" replicaof 192.168.0.7 6379 masterauth 123456789 masteruser worker cluster-config-file /opt/local/redis/cluster/nodes-6380.conf
启动
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 redis-server /opt/local/redis/redis_6379.conf redis-server /opt/local/redis/redis_6380.conf ps -ef | grep redis redis-cli -u redis://worker:123456789@localhost:6379/0 -a 123456789 info replication redis-cli -p 6379 -a 123456789 info replication # 这种方式只能连接default用户 redis-cli -p 6379 # 连接redis,默认端口6379 auth default 123456789 info replication acl list select 0 # 切换数据库 dbsize # 查看当前数据库的key的数量 flushdb # 清空当前库 flushall # 清空所有库 acl list ll /root/.cache/vmware/drag_and_drop/ rm -rf /root/.cache/vmware/drag_and_drop/*
哨兵配置文件–使用中 请在上述节点配置文件中,关闭集群模式,并配置主从关系。
编辑哨兵配置文件 vim /opt/local/redis/redis_sentinel_26379.conf
。或从解压目录复制一份哨兵配置文件后再修改:cp /opt/local/redis-7.4.0/sentinel.conf /opt/local/redis/redis_sentinel_26379.conf
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 protected-mode no port 26379 daemonize yes pidfile /opt/local/redis/pid/redis_sentinel_26379.pid loglevel notice logfile "/opt/local/redis/log/redis_sentinel_26379.log" user worker on ~* &* +@all >123456789 requirepass 123456789 sentinel monitor mymaster 192.168.0.7 6379 1 sentinel auth-pass mymaster 123456789 sentinel auth-user mymaster worker sentinel sentinel-user worker sentinel sentinel-pass 123456789
启动
sentinel不是数据节点,而是监控节点,所以在nodes节点无法运行select、keys等命令。
1 2 3 4 5 6 7 8 9 redis-sentinel /opt/local/redis/redis_sentinel_26379.conf ps -ef | grep redis redis-cli -u redis://worker:123456789@localhost:26379/0 -a 123456789 info sentinel redis-cli -p 26379 -a 123456789 info sentinel # 这种方式只能连接default用户 redis-cli -p 26379 #-a 123456789 # 连接sentinel,默认端口26379 auth sentinel-worker 123456789 info sentinel acl list
注意:
反客为主后,会对原salve的配置进行rewrite( Redis Config rewrite 命令 ),而原master节点重新启动并不会成为现master节点的salve,需要重新配置。
开机自启 1 2 3 4 5 6 yum install chkconfig # centos stream9 必须在init文件创建前安装,否则目录已存在则安装失败,可能是系统bug # 从redis解压包复制init脚本,然后修改启动文件 # cp /opt/local/redis-7.4.0/utils/redis_init_script /etc/init.d/redis# 或直接新增启动文件 vim /etc/init.d/redis
启动文件内容如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 # !/bin/sh # # as it does use of the /proc filesystem. # # Provides: redis_6379 # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: Redis data structure server # Description: Redis data structure server. See https://redis.io # REDISPORT_6379=6379 PIDFILE_6379=/opt/local/redis/pid/redis_${REDISPORT_6379}.pid CONF_6379="/opt/local/redis/redis_${REDISPORT_6379}.conf" REDISPORT_6380=6380 PIDFILE_6380=/opt/local/redis/pid/redis_${REDISPORT_6380}.pid CONF_6380="/opt/local/redis/redis_${REDISPORT_6380}.conf" REDIS_SENTINELPORT_26379=26379 PIDFILE_26379=/opt/local/redis/pid/redis_sentinel_${REDIS_SENTINELPORT_26379}.pid CONF_26379="/opt/local/redis/redis_sentinel_${REDIS_SENTINELPORT_26379}.conf" EXEC=/opt/local/redis/bin/redis-server SLEXEC=/opt/local/redis/bin/redis-sentinel CLIEXEC=/opt/local/redis/bin/redis-cli case "$1" in start) if [ -f $PIDFILE_6379 ] then echo "$PIDFILE_6379 exists, process is already running or crashed" else echo "Starting Redis $REDISPORT_6379 server..." $EXEC $CONF_6379 fi sleep 1 if [ -f $PIDFILE_6380 ] then echo "$PIDFILE_6380 exists, process is already running or crashed" else echo "Starting Redis $REDISPORT_6380 server..." $EXEC $CONF_6380 fi sleep 1 if [ -f $PIDFILE_26379 ] then echo "$PIDFILE_26379 exists, process is already running or crashed" else echo "Starting Redis $REDIS_SENTINELPORT_26379 server..." $SLEXEC $CONF_26379 fi ;; stop) if [ ! -f $PIDFILE_6379 ] then echo "$PIDFILE_6379 does not exist, process is not running" else PID_6379=$(cat $PIDFILE_6379) echo "Stopping $REDISPORT_6379 ..." $CLIEXEC -u redis://worker:123456789@localhost:6379/0 -a 123456789 --no-auth-warning shutdown while [ -x /proc/${PID_6379} ] do echo "Waiting for Redis $REDISPORT_6379 to shutdown ..." sleep 1 done echo "Redis $REDISPORT_6379 stopped" fi sleep 1 if [ ! -f $PIDFILE_6380 ] then echo "$PIDFILE_6380 does not exist, process is not running" else PID_6380=$(cat $PIDFILE_6380) echo "Stopping $REDISPORT_6380 ..." $CLIEXEC -u redis://worker:123456789@localhost:6380/0 -a 123456789 --no-auth-warning shutdown while [ -x /proc/${PID_6380} ] do echo "Waiting for Redis $REDISPORT_6380 to shutdown ..." sleep 1 done echo "Redis $REDISPORT_6380 stopped" fi sleep 1 if [ ! -f $PIDFILE_26379 ] then echo "$PIDFILE_26379 does not exist, process is not running" else PID_26379=$(cat $PIDFILE_26379) echo "Stopping $REDIS_SENTINELPORT_26379 ..." $CLIEXEC -u redis://worker:123456789@localhost:26379/0 -a 123456789 --no-auth-warning shutdown while [ -x /proc/${PID_26379} ] do echo "Waiting for Redis $REDIS_SENTINELPORT_26379 to shutdown ..." sleep 1 done echo "Redis $REDIS_SENTINELPORT_26379 stopped" fi ;; *) echo "Please use start or stop as first argument" ;; esac
修改文件权限
1 chmod 777 /etc/init.d/redis
启动
1 2 service redis start service redis stop # 如果失败,请检查/etc/init.d/redis脚本中的redis密码
设置开机启动
1 2 3 # 设置 redis 服务在运行级别为2、3、4、5时启动。--level 指定读系统服务要在哪一个Linux运行级别中开启或关闭。 chkconfig --level 2345 redis on chkconfig --level 2345 redis off
集群管理 请在上述节点配置文件中,开启集群模式,并取消主从关系。
redisz主从集群最少需要6个节点。
1 2 3 4 5 cd /opt/local/redis cp redis_6380.conf redis_6381.conf cp redis_6380.conf redis_6389.conf cp redis_6380.conf redis_6390.conf cp redis_6380.conf redis_6391.conf
修改配置文件,启动6个服务
1 2 3 4 5 6 redis-server /opt/local/redis/redis_6379.conf redis-server /opt/local/redis/redis_6380.conf redis-server /opt/local/redis/redis_6381.conf redis-server /opt/local/redis/redis_6389.conf redis-server /opt/local/redis/redis_6390.conf redis-server /opt/local/redis/redis_6391.conf
redis-trib.rb 是官方提供的Redis Cluster的管理工具,无需额外下载,默认位于源码包的src目录下。
1 2 3 4 5 6 7 8 9 10 11 # 将六个节点合成一个集群,组合之前,请确保所有redis实例启动后,nodes-xxxx.conf文件都生成正常。 cd /opt/local/redis-7.4.0/src/ # 必须在此目录下执行 # 此处不要用127.0.0.1,请用真实IP地址 redis-cli --cluster create --cluster-replicas 1 -a 123456789 \ 192.168.0.7:6379 \ 192.168.0.7:6380 \ 192.168.0.7:6381 \ 192.168.0.7:6389 \ 192.168.0.7:6390 \ 192.168.0.7:6391
Redis集群的不足
多键操作是不被支持的
多键的Redis事务是不被支持的。lua脚本不被支持
由于集群方案出现较晚,很多公司已经采用了其他的集群方案,而代理或者客户端分片的方案想要迁移至redis cluster,需要整体迁移而不是逐步过渡,复杂度较大。
windows https://www.redis.com.cn/redis-installation.html
https://www.runoob.com/redis/redis-install.html 附下载地址
1 2 3 4 5 6 7 8 9 10 11 12 13 # 安装Redis服务 redis-server.exe --service-install redis.windows-service.conf --service-name Redis --loglevel verbose # 启动 redis-server --service-start # 测试 redis-cli.exe -h 127 .0 .0 .1 -p 6379 # 停止 redis-server --service-stop # 卸载Redis服务 redis-server --service-uninstall sc delete Redis
redis.windows.conf 和 redis.windows-service.conf 的以下配置不同
1 2 3 logfile "server_log.txt" syslog-enabled yes syslog-ident redis
redis.windows-service.conf 旨在作为服务/守护程序运行。这意味着它应该在后台运行并由操作系统管理(在重新启动时启动,如果崩溃则重新启动等)。 redis.windows.conf 旨在从命令行或脚本运行并在用户空间中进行管理。 两者之间唯一的实质性区别是服务挂钩到 Windows 系统日志中,这对于服务来说是一个非常好的主意,但对于正常进程来说通常是不必要的。 无论选择哪一种,都需要根据自己的目的对其进行调整。它们只是作为样本。
Redis客户端 1 2 3 4 5 6 7 8 9 10 11 12 -h <hostname> Server hostname (default: 127.0.0.1) # 指定ip -p <port> Server port (default: 6379) # 指定端口,默认是6379 -a <password> Password to use when connecting to the server # 连接密码 -n <db> Database number # 指定的数据库 # 登录时指定密码,不安全,可以在历史命令中查到 redis-cli -h 127.0.0.1 -p port -a 123456 -n 0 # 不指定密码 redis-cli -h 127.0.0.1 -p 6379 -n 0 auth 123456
Redis五种数据类型 Redis 没有专门的整数类型
string 是 redis 最基本的数据类型,一个 key 对应一个 value。
string 类型是二进制安全的。意思是 redis 的 string 可以包含任何数据。比如jpg图片或者序列化的对象。
基本命令
请参阅字符串命令的完整列表 。
指标管理
按位运算
要对字符串执行按位运算,请参阅位图数据类型 文档。
表现
大多数字符串操作都是O(1),这意味着它们的效率很高。但是,请小心使用SUBSTR
复杂GETRANGE
度SETRANGE
命令,这些命令可以是O(n)。这些随机访问字符串命令在处理大字符串时可能会导致性能问题。
限制
默认情况下,单个 Redis 字符串最大为 512MB 。
例子
1 2 3 4 del mykey set mykey "Hello\nWorld" OK get mykey
Redis 列表是简单的字符串列表,按照插入顺序排序。可以添加一个元素到列表的头部(左边)或者尾部(右边)。
每个列表最多可存储 232 - 1 个元素(40多亿 )。
Redis 列表经常用于:
基本命令
请参阅完整的列表命令系列 。
阻塞命令
列表支持多种阻塞命令。例如:
BLPOP
从列表的头部移除并返回一个元素。如果列表为空,则命令将阻塞,直到元素可用或达到指定的超时为止。
BLMOVE
原子地将元素从源列表移动到目标列表。如果源列表为空,则该命令将阻塞,直到有新元素可用为止。
表现
访问其头部或尾部的列表操作的复杂度为 O(1),这意味着它们非常高效。但是,操作列表中元素的命令通常是 O(n)。这些示例包括LINDEX
、LINSERT
和LSET
。运行这些命令时要小心,特别是在对大型列表进行操作时。
限制
List的最大长度为 232 - 1(40多亿 )。
例子
将列表视为队列(先进先出):
1 2 3 4 5 6 7 8 9 del ids lpush work:queue:ids 1 lpush work:queue:ids 2 lpush work:queue:ids 3 rpop work:queue:ids "1" rpop work:queue:ids "2"
将列表视为堆栈(先进后出):
1 2 3 4 5 6 7 8 9 del ids lpush work:queue:ids 1 lpush work:queue:ids 2 lpush work:queue:ids 3 lpop work:queue:ids "3" lpop work:queue:ids "2"
检查列表的长度:
1 2 llen work:queue:ids (integer) 1
创建一个上限为100个元素的列表,可以在每次调用 LPUSH 后调用 LTRIM :
1 2 3 4 lpush notifications:user:1 "You've got mail!" ltrim notifications:user:1 0 99 lpush notifications:user:1 "Your package will be delivered at 12:01 today." ltrim notifications:user:1 0 99
Redis 的 Set 是唯一 string 类型元素的无序集合 。
可以使用 Redis 集来高效地:
跟踪唯一项目(例如,跟踪访问给定博客文章的所有唯一 IP 地址)。
表示关系(例如,具有给定角色的所有用户的集合)。
执行常见的集合运算,例如交集、并集和差集。
基本命令
请参阅set 命令的完整列表 。
表现
集合是通过哈希表实现的,所以大多数集合操作,包括添加、删除和检查项是否为集合成员,复杂度都是O(1)。这意味着它们的效率很高。
但是,对于具有数十万或更多成员的大型集,在运行 SMEMBERS 命令 时,应谨慎 行事。此命令为O(n),并在单个响应中返回整个集合。作为另一种选择,可以考虑SSCAN,它允许您迭代地检索集合的所有成员。
限制
每个集合的最大成员数为 232 - 1(40多亿 )。
例子
存储用户 123 和 456 的收藏书 ID 集:
1 2 3 4 5 6 7 sadd user:123:favorites 347 sadd user:123:favorites 561 sadd user:123:favorites 742 sadd user:456:favorites 561 sadd user:456:favorites 99999 srem user:456:favorites 99999
检查用户 123 是否喜欢书籍 742 和 299
1 2 sismember user:123:favorites 742 sismember user:123:favorites 299
用户 123 和 456 有没有共同喜欢的书?
1 sinter user:123:favorites user:456:favorites
用户 123 收藏了多少本书?
1 scard user :123 :favorites
Redis hash 是一个键值对集合 (key=>value)。
Redis hash 是一个 string 类型的 field 和 value 的映射表(field=>value对),hash 特别适合用于存储对象 。
基本命令
请参阅哈希命令的完整列表 。
表现
大多数 Redis 哈希命令的复杂度为 O(1)。
一些命令 - 例如HKEYS
、HVALS
和HGETALL
- 是 O(n),其中n 是字段值对的数量。
限制
每个 hash 可以存储 232 - 1 个 键值对 (40多亿 )。实际上,仅受托管 Redis 部署的 VM 上的总内存的限制。
例子
将用户对象存储为散列
1 2 3 4 del zhangsan hset zhangsan sno 2022020037 name zhagnsan age 18 sex 1 hget zhangsan sno hgetall zhangsan
存储设备 777 对服务器执行 ping 操作、发送错误或发出请求的次数的计数器
1 2 3 4 5 6 7 8 del device:777:stats hincrby device:777:stats pings 1 # key为pings的value加1 hincrby device:777:stats pings 1 hincrby device:777:stats pings 10 # key为pings的value加10 hincrby device:777:stats errors 1 # key为errors的value加1 hincrby device:777:stats requests 1 # key为requests的value加1
Redis zset 和 set 一样,也是唯一 string 类型元素的集合。
不同的是,每个元素都会关联一个double类型的分数 ,通过分数为集合中的成员排序 (从大到小)。成员是唯一,分数(score)却可以重复。
当多个字符串具有相同的分数时,字符串按字典顺序排列。zset 的示例:
排行榜。使用排序集轻松维护大型在线游戏中最高分的有序列表。
速率限制器。使用 zset 来构建滑动窗口速率限制器,以防止过多的 API 请求。
基本命令
请参阅排序集命令的完整列表 。
ZADD
将新成员和关联的分数添加到已排序的集合中。如果该成员已经存在,则更新分数。
ZRANGE
返回在给定范围内排序的有序集合的成员。
ZRANK
返回所提供成员的排名,假设排序是按升序排列。
ZREVRANK
返回所提供成员的排名,假设排序集按降序排列。
表现
大多数有序集合操作的复杂度为 O(log(n)),其中n 是成员数。
ZRANGE
运行具有较大返回值(例如,数万或更多)的命令时要小心。此命令的时间复杂度为 O(log(n) + m),其中m 是返回的结果数。
备择方案
Redis 排序集有时用于索引其他 Redis 数据结构。如果您需要索引和查询您的数据,请考虑RediSearch 和RedisJSON 。
限制
每个集合的最大成员数为 232 - 1(40多亿 )。
例子
随着玩家分数的变化更新实时排行榜
1 2 3 4 5 6 7 ZADD leaderboard:455 100 user:1 ZADD leaderboard:455 75 user:2 ZADD leaderboard:455 101 user:3 ZADD leaderboard:455 15 user:4 ZADD leaderboard:455 275 user:2 # 请注意,在最后一次调用user:2中更新了 score 。ZADD
获取前 3 名玩家的分数
1 2 3 4 5 6 7 ZRANGE leaderboard:455 0 2 REV WITHSCORES 1) "user:2" 2) "275" 3) "user:3" 4) "101" 5) "user:1" 6) "100"
用户 2 的排名是多少?
1 2 ZREVRANK leaderboard:455 user:2 (integer) 0