redis学习笔记
目录
0.引言
redis是一个开源的,使用c语言编写的基于内存、网络、也可以进行持久化的key- value数据库,可当作缓存、数据库、消息队列使用,支持多种数据类型:String、Set、zSet、hash、list等类型,提供多种语言API。
1.安装
1.redis官网:
中文网:https://www.redis.net.cn/
2.下载文件
3.linux安装步骤
(1).用访达在同一目录下运行指令:tar xzf redis-6.0.9.tar.gz,解析出reids-x.x.x文件夹
(2).cd进入redis-x.x.x目录 cd redis-x.x.x
(3).运行make指令编译redis
(4).运行 src/redis-serve 启动服务端(不要关闭访达窗口)
(5).重新启动一个访达窗口进入redis-x.x.x目录运行 src/redis-cli 启动redis客户端(使用ping测试是否成功:返回PONG)
4.备注
1.在自己电脑可以通过开启多个访达窗口来进行服务器端与客户端的访问,在服务器 端可以使用nohup &指令来启动服务器端。默认服务器端口号6379.
2.在服务器端使用客户端连接服务端时执行 redis-cli -h host -p port -a password 指令, -h跟随服务器地址,-p跟随端口号,-a跟随密码
3.通过密码验证连接到 redis 服务
redis 127.0.0.1:6379> AUTH "password"
OK
redis 127.0.0.1:6379> PING
PONG
5.数据库指令
1.Redis Flushdb 命令用于清空当前数据库中的所有 key。
redis 127.0.0.1:6379> FLUSHDB
OK
2.Redis Flushall 命令用于清空整个 Redis 服务器的数据(删除所有数据库的所有 key )。
redis 127.0.0.1:6379> flushall # 清空所有数据库的所有 key
OK
3.Redis Dbsize 命令用于返回当前数据库的 key 的数量。
redis 127.0.0.1:6379> DBSIZE
(integer) 5
4.Redis Ping 命令使用客户端向 Redis 服务器发送一个 PING ,如果服务器运作正 常的话,会返回一个 PONG 。
redis 127.0.0.1:6379> PING
PONG
5.Redis Select 命令用于切换到指定的数据库,数据库索引号 index 用数字值指。 定,以 0 作为起始索引值。
redis 127.0.0.1:6379> SELECT 1 # 使用 1 号数据库
OK
2.类型
Redis支持五种数据类型:
1.String类型
Redis最基本的数据类型,与Memcached中的类型相同。一个key对应一个value,并 且是二进制安全的。它的值最大能存储512MB。指令:
SET:用于设置字符串值。
127.0.0.1:6379> set testString testValue
OK
GET:用于获取字符串值。
127.0.0.1:6379> get testString
"testValue"
MSET:同时设置多个字符串值。
127.0.0.1:6379> mset q 1 w 2 e 3 r 4
OK
MGET:同时获取多个字符串值。
127.0.0.1:6379> mget q w eee
1) "1"
2) "2"
3) (nil)
EXISTS:检查字符串是否存在。
127.0.0.1:6379> exists q w e r
(integer) 4
DEL:删除字符串。
127.0.0.1:6379> del testString
(integer) 1
APPEND:向字符串追加值。
127.0.0.1:6379> append testString 123
(integer) 12
SUBSTR:获取字符串的子串。
127.0.0.1:6379> substr testString 0 5
"testVa"
INCR:将字符串值递增。
127.0.0.1:6379> incr q
(integer) 2
DECR:将字符串值递减
127.0.0.1:6379> decr q
(integer) 1
INCRBY:将字符串值递增指定的步长。
127.0.0.1:6379> incrby q 123
(integer) 124
DECRBY:将字符串值递减指定的步长。
127.0.0.1:6379> decrby q 19
(integer) 105
PSETEX:设置带过期时间的字符串值。
127.0.0.1:6379> psetex i 10000 2
OK
127.0.0.1:6379> ttl i
(integer) 6
127.0.0.1:6379> ttl i
(integer) 4
EXPIRE:设置字符串值的过期时间。
127.0.0.1:6379> expire w 100000
(integer) 1
127.0.0.1:6379> ttl w
(integer) 99995
EXPIREAT:设置字符串值的过期时间戳。
127.0.0.1:6379> expireat e 1000
(integer) 1
127.0.0.1:6379> ttl e
(integer) -2
2.Hash类型
Redis hash 是一个键值对集合。一个string类型的field和value的映射表,特别适合用 于存储对象。指令:
HSET:用于设置Hash中字段的值。语法为HSET key field value,其中key是Hash
的键名,field是字段名,value是字段值。
127.0.0.1:6379> hset testHash name hash age 15 memo isMemo
(integer) 3
127.0.0.1:6379> hkeys testHash
1) "name"
2) "age"
3) "memo"
HGET:用于获取Hash中字段的值。语法为HGET key field,其中key是Hash的键
名,field是字段名。
127.0.0.1:6379> hget testHash name
"hash"
HEXISTS:用于检查Hash中是否存在指定的字段。语法为HEXISTS key field,其
中key是Hash的键名,field是字段名。
127.0.0.1:6379> hexists testHash name
(integer) 1
127.0.0.1:6379> hexists testHash noName
(integer) 0
HLEN:用于获取Hash中字段的数量。语法为HLEN key,其中key是Hash的键名
HDEL:用于删除Hash中的字段。语法为HDEL key field [field ...],其中key是
Hash的键名,field是要删除的字段名。
127.0.0.1:6379> hlen testHash
(integer) 3
127.0.0.1:6379> hdel testHash memo
(integer) 1
127.0.0.1:6379> hlen testHash
(integer) 2
HKEYS:用于获取Hash中所有字段的列表。语法为HKEYS key,其中key是Hash
的键名。
127.0.0.1:6379> hkeys testHash
1) "name"
2) "age"
HVALS:用于获取Hash中所有字段值的列表。语法为HVALS key,其中key是
Hash的键名。
127.0.0.1:6379> hvals testHash
1) "hash"
2) "15"
HGETALL:用于获取Hash中所有字段和值的对应关系。语法为HGETALL key,其
中key是Hash的键名。
127.0.0.1:6379> hgetall testHash
1) "name"
2) "hash"
3) "age"
4) "15"
3.列表List
列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素导列表的头部(左边)或者尾部(右边)。指令:
LPUSH:将一个或多个值插入到列表头部。语法为LPUSH key value [value ...],其中 key是列表的键名,value是要插入的值。
127.0.0.1:6379> lpush testList n1 v1
(integer) 2
RPUSH:将一个或多个值插入到列表尾部。语法为RPUSH key value [value ...],其中 key是列表的键名,value是要插入的值。
127.0.0.1:6379> rpush testList rightOne
(integer) 3(已经插入了两条)
LPOP:移除并返回列表头部的第一个元素。语法为LPOP key,其中key是列表的键 名。
127.0.0.1:6379> lpop testList 1
1) "n1"
127.0.0.1:6379> llen testList
(integer) 2
RPOP:移除并返回列表尾部的最后一个元素。语法为RPOP key,其中key是列表的键 名。
127.0.0.1:6379> rpop testList 1
1) "rightOne"
127.0.0.1:6379> llen testList
(integer) 1
LINDEX:获取列表在给定位置上的元素。语法为LINDEX key index,其中key是列表的 键名,index是位置索引(从0开始)。
127.0.0.1:6379> lpush testList 1 2 3 4
(integer) 5
127.0.0.1:6379> lindex testList 0
"4"
LRANGE:返回列表中指定范围内的元素。语法为LRANGE key start stop,其中key是 列表的键名,start和stop是指定范围的起始和结束索引。
127.0.0.1:6379> lpush testList 1 2 3 4
(integer) 5
127.0.0.1:6379> lrange testList 0 2
1) "4"
2) "3"
3) "2"
LLEN:获取列表的长度。语法为LLEN key,其中key是列表的键名。
127.0.0.1:6379> llen testList
(integer) 5
LTRIM:修剪(或减少)一个已存在的列表,使其保留在指定的范围内。语法为LTRIM key start stop,其中key是列表的键名,start和stop是指定范围的起始和结束索引。
127.0.0.1:6379> ltrim testList 0 2
OK
127.0.0.1:6379> llen testList
(integer) 3
127.0.0.1:6379> lrange testList 0 2
1) "4"
2) "3"
3) "2"
127.0.0.1:6379>
4.Set集合类型
Redis的Set是string类型的无序集合。集合是通过哈希表实现的,所以添加,删除,查找
的复杂度都是O(1)。指令:
SADD:将一个或多个元素添加到集合中。语法为SADD key member [member ...],其
中key是集合的键名,member是要添加的元素。
127.0.0.1:6379> sadd testSet 1 2 3 4 5
(integer) 5
SMEMBERS:获取集合中的所有元素。语法为SMEMBERS key,其中key是集合的键
名。
127.0.0.1:6379> smembers testSet
1) "1"
2) "2"
3) "3"
4) "4"
5) "5"
SREM:从集合中移除一个或多个元素。语法为SREM key member [member ...],其中
key是集合的键名,member是要移除的元素。
127.0.0.1:6379> srem testSet 1
(integer) 1
127.0.0.1:6379> smembers testSet
1) "2"
2) "3"
3) "4"
4) "5"
SISMEMBER:检查元素是否存在于集合中。语法为SISMEMBER key member,其中
key是集合的键名,member是要检查的元素。
127.0.0.1:6379> sismember testSet 2
(integer) 1
127.0.0.1:6379> sismember testSet 1
(integer) 0
SCARD:获取集合中的元素数量。语法为SCARD key,其中key是集合的键名。
127.0.0.1:6379> scard testSet
(integer) 4
SPOP:移除并返回集合中的一个随机元素。语法为SPOP key,其中key是集合的键
名。
127.0.0.1:6379> spop testSet
"3"
5.ZSet有序集合类型
Redis zset 和 set 一样也是string类型元素的集合,且不允许重复的成员。不同的是每个元素都会关联一个double类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序zset的成员是唯一的,但分数(score)却可以重复。指令:
ZADD:将一个或多个元素添加到有序集合中,或者更新已存在元素的分数。语法为ZADD key score member [score member ...],其中key是有序集合的键名,score是元素的分数,member是要添加的元素。
127.0.0.1:6379> zadd testZSet 100 1
(integer) 1
ZREM:从有序集合中移除一个或多个元素。语法为ZREM key member [member ...],其中key是有序集合的键名,member是要移除的元素。
127.0.0.1:6379> zrem testZSet 2
(integer) 0
ZSCORE:获取有序集合中指定元素的分数。语法为ZSCORE key member,其中key是有序集合的键名,member是要查询的元素。
127.0.0.1:6379> zscore testZSet 1
"100"
ZINCRBY:增加有序集合中指定元素的分数。语法为ZINCRBY key increment member,其中key是有序集合的键名,increment是增加的分数值,member是要增加分数的元素。
127.0.0.1:6379> zincrby testZSet 100 1
"200"
ZCARD:获取有序集合中的元素数量。语法为ZCARD key,其中key是有序集合的键名。
127.0.0.1:6379> zcard testZSet
(integer) 1
ZRANGE:返回有序集合中指定分数范围内的元素。语法为ZRANGE key start stop [WITHSCORES],其中key是有序集合的键名,start和stop是指定分数范围的起始和结束值,可选参数WITHSCORES表示是否返回元素的分数。
ZREVRANGE:返回有序集合中指定分数范围内的元素,按分数从高到低排序。语法与ZRANGE相同,只是排序顺序相反。
ZRANK:返回有序集合中指定元素的排名(按分数从低到高)。语法为ZRANK key member,其中key是有序集合的键名,member是要查询排名的元素。
ZREVRANK:返回有序集合中指定元素的排名(按分数从高到低)。语法与ZRANK相同,只是排序顺序相反。
结束。
3.发布订阅功能
Redis 发布订阅(pub/sub)是一种消息通信模式:发送者(pub)发送消息,订阅者(sub)接收消息。客户端可以订阅任意数量的频道。
1.指令:
1 | PSUBSCRIBE pattern [pattern ...] 订阅一个或多个符合给定模式的频道。 |
2 | PUBSUB subcommand [argument [argument ...]] 查看订阅与发布系统状态。 |
3 | PUBLISH channel message 将信息发送到指定的频道。 |
4 | PUNSUBSCRIBE [pattern [pattern ...]] 退订所有给定模式的频道。 |
5 | SUBSCRIBE channel [channel ...] 订阅给定的一个或多个频道的信息。 |
6 | UNSUBSCRIBE [channel [channel ...]] 指退订给定的频道。 |
2.应用场景
消息通知:发布订阅模式可以用于实现消息通知功能。例如,当某个事件发生时,你可 以使用Redis发布订阅功能将消息发送到特定的频道。订阅了这个频道的所有客户端都能接 收到这条消息,从而实现实时通知。
群聊:Redis的发布订阅功能也可以用于实现群聊功能。例如,在一个聊天室中,你可 以将聊天室作为一个频道,所有的聊天者都是订阅者。当有新的消息发送到这个频道时, 所有订阅了这个频道的客户端都能接收到这条消息,从而实现群聊功能。
定向推送:如果你需要向特定的用户推送消息,你也可以使用Redis的发布订阅功能。 例如,你可以将用户ID作为频道,将需要推送的消息发送到这个频道。所有订阅了该用户 ID的客户端都能接收到这条消息,从而实现定向推送。
参数刷新加载:在某些情况下,你可能需要定期刷新或加载某些参数。例如,你可能需 要定期从数据库或其他数据源获取最新数据,并将其发送给客户端。你可以使用Redis的发 布订阅功能来实现这个功能。你可以将参数更新作为一个频道,将需要更新的客户端订阅 到这个频道。当参数更新时,你可以将更新后的参数发送到这个频道。所有订阅了这个频道 的客户端都能接收到最新的参数,从而实现参数的自动刷新和加载。
4.事务
介绍
Redis 事务可以一次执行多个命令, 并且带有以下两个重要的保证:
事务是一个单独的隔离操作:事务中的所有命令都会序列化、按顺序地执行。
事务在执行的过程中,不会被其他客户端发送来的命令请求所打断。
事务是一个原子操作:事务中的命令要么全部被执行,要么全部都不执行。
一个事务从开始到执行会经历以下三个阶段:
开始事务、命令入队、执行事务。
指令
序号 | 命令及描述 |
---|---|
1 | DISCARD 取消事务,放弃执行事务块内的所有命令。 |
2 | EXEC 执行所有事务块内的命令。 |
3 | MULTI 标记一个事务块的开始。 |
4 | UNWATCH 取消 WATCH 命令对所有 key 的监视。 |
5 | WATCH key [key ...] 监视一个(或多个) key ,如果在事务执行之前这个(或这些) key 被其他命令所改动,那么事务将被打断。 |
redis 127.0.0.1:6379> MULTI
OK
redis 127.0.0.1:6379> SET book-name "Mastering C++ in 21 days"
QUEUED
redis 127.0.0.1:6379> GET book-name
QUEUED
redis 127.0.0.1:6379> SADD tag "C++" "Programming" "Mastering Series"
QUEUED
redis 127.0.0.1:6379> SMEMBERS tag
QUEUED
redis 127.0.0.1:6379> EXEC
1) OK
2) "Mastering C++ in 21 days"
3) (integer) 3
4) 1) "Mastering Series"
2) "C++"
3) "Programming"
5.主从复制
1.介绍
一种数据处理(备份)机制,主机更新数据后根据配置的策略自动同步给从机(备份机),通常情况下Master写为主、Slave读为主。
2.优缺点
Redis主从复制的优点包括:
数据备份和恢复:从节点可以作为数据备份,保证在主节点宕机或丢失数据时可以
快速恢复。
读写分离:从节点只能读取数据,减轻主节点压力,提高读性能。
高可用性:当主节点宕机时,从节点可以自动切换为主节点继续提供服务。
扩展性:通过加入更多的从节点,可以实现横向扩展,增加集群处理能力。
Redis主从复制的缺点包括:
延迟:因为主节点需要广播数据给从节点,所以会有一定的网络传输延迟。
容灾能力:如果所有从节点挂掉,那么这个集群的容灾能力就很差了。
一致性问题:由于Redis的异步复制机制,当主节点数据有修改而还未同步到
从节点时,此时主节点宕机,数据可能会出现不一致的情况。
3.步骤
1.首先准备三个文件夹,对应三个redis服务,端口号分别为6379、6380、6381。
(一般修改redis.conf文件或者redis.windows.conf文件端口号就可以)
2.启动redis-serve,在redis目录下cmd,输入redis-serve.exe redis.windows.conf
redis-serve.exe redis.windows.conf
连接redis,在redis目录下cmd,输入redis-cli.exe -h 127.0.0.1 -p 6379
redis-cli.exe -h 127.0.0.1 -p 6379
3.使用info replication查看redis服务状态,起始状态都是主数据库
info replication
4.使用slaveof 127.0.0.1 6379在6380、6381上连接6379,成为两个从数据库
slaveof 127.0.0.1 6379
5.查看6379状态,可以看到两台从服务器连接
6.此时在6379添加数据,数据就会同步到6380与6381
6.Redis哨兵
1.介绍
主要用于解决Redis主从复制模式中主服务器宕机后需要手动切换从服务器的问题。哨兵
模式通过自动监控、自动故障转移和自动通知,极大地提高了Redis的高可用性。
2.原理
1 | 监控与发现 | 哨兵节点负责监控Redis主从节点的运行状态。它们定期发送消息给这些节点,并等待响应,以此了解每个节点的健康状况。 |
2 | 故障检测 | 如果某个哨兵节点在一定时间内没有收到主节点的响应,它会认为主节点可能已故障,并投出一票“主观下线”。当多个哨兵节点都投出类似的票数并达到一定阈值时,主节点会被判定为“客观下线”,即确认发生故障。 |
3 | 自动故障转移 | 一旦主节点被判定为故障,哨兵节点会启动自动故障转移过程。它们会选举出一个领导者来负责这一操作,然后选择一个从节点作为新的主节点。选举过程会考虑从节点的优先级、复制进度等因素。 |
4 | 通知与更新 | 新的主节点选定后,哨兵节点会更新集群配置,并通知其他哨兵节点和从节点进行相应的更新。同时,哨兵也会通知客户端新的主节点地址,以便客户端可以无缝地连接到新的主节点继续服务。 |
3.优缺点
优点 | 缺点 |
高可用性:哨兵模式通过自动进行主从切换,可以在主节点故障时迅速选出新的主节点,从而确保Redis服务的不间断运行,大大提高了系统的可用性。 | 复杂性增加:引入哨兵模式后,需要对集群进行额外的配置和管理,增加了系统的复杂度。同时,哨兵节点本身也可能成为故障点,需要对其进行监控和维护。 |
自动故障转移:哨兵模式可以自动检测节点的健康状况,并在主节点故障时自动触发故障转移过程,无需人工干预,降低了运维成本。 | 性能开销:哨兵进程会增加系统的负载,可能导致性能下降。此外,由于哨兵需要进行频繁的状态检查和转移操作,可能会对系统带来一定的延迟。 |
扩展性:哨兵模式支持通过添加Redis从实例来扩展系统的读取能力,同时不影响主Redis实例的写入能力,使得系统可以更加灵活地应对流量增长的需求。 | 资源浪费:在哨兵模式中,从节点作为备份节点不提供服务,这在一定程度上造成了资源的浪费。 |
在线扩容困难:Redis在哨兵模式下不好在线扩容,一旦集群容量达到上限,进行扩容就会变得十分麻烦。 |
4.步骤
1.分别在6379、6380、6381文件夹下的conf文件夹新建一个sentinel.conf文件
2.sentinel.conf文件内容,分别对应其reids端口
# 哨兵服务端口
port 26381
# 是否守护线程
daemonize yes
# 是否仅接受本地连接
protected-mode no
# 监听的 IP 地址
bind 127.0.0.1
# 监控的主服务器
sentinel monitor mymaster 127.0.0.1 6381 2
# 主服务器在 5 秒内没有响应 Sentinel 的 ping 请求,Sentinel 就会认为主服务器已经不可达
sentinel down-after-milliseconds mymaster 5000
# 这是故障转移的超时时间
sentinel failover-timeout mymaster 15000
# 主服务器的密码
sentinel auth-pass mymaster 123456
3.分别启动redis服务、哨兵sentinel服务(先启动redis服务)
redis-server.exe sentinel.conf --sentinel
#启动哨兵服务
4.查看当前3个redis服务关系(一主二从)
5.挂掉6379端口redis服务
6.查看当前6380、6381端口redis服务状态
此时6381端口的redis服务晋升为了主数据库,此时再启动6379端口redis服务
可见6379端口redis服务成为了6381端口redis服务的从数据库
7.Redis集群
1.介绍
Redis集群提供了一种高效且可靠的方式,在多个Redis节点间共享数据,同时保证
了数据的可用性和性能。
2.原理
Redis集群通过数据分片、主从复制、节点通信和故障转移等机制,实现了高可用
性和可扩展性的数据存储和处理。这使得Redis集群能够应对大规模数据的存储和访问需
求,成为许多分布式应用的首选数据存储解决方案。
3.分区规则
规则 | 解释 | 优点 | 缺点 |
节点取余分区 | 使用哈希函数(如hash(key) )将键映射为一个整数,然后对这个整数进行取余操作(% N ),其中N 是集群中节点的数量。 | 简单且易于实现 | 当节点数量变化时,需要重新计算所有键的哈希值并进行取余,导致数据需要重新迁移。 |
一致性哈希分区 | 一致性哈希分区使用哈希环的概念,其中每个节点在环上都有一个唯一的位置(或称为token)。当需要确定一个键属于哪个节点时,首先计算键的哈希值,然后在环上顺时针查找第一个大于或等于该哈希值的节点。 | 节点的增减只会影响相邻节点的数据,对集群的影响较小 | 1.当节点增减时,可能需要进行数据迁移,但由于影响范围有限,相对于节点取余分区,其影响更小。 2.维护哈希环和节点状态可能需要更多的计算和通信成本 |
哈希槽分区(Redis Cluster采用的分区规则) | Redis Cluster使用哈希槽分区来管理数据。它定义了16384个槽,每个槽负责存储一部分数据。集群中的每个节点可以负责一个或多个槽。 | 1.提供了良好的数据分布和负载均衡。 2.节点增减时,只需要迁移部分槽的数据。 3.官方提供了自动故障转移和动态扩展的功能。 |
4.优缺点
优点 | 缺点 |
良好的可伸缩性:Redis集群支持像添加单台服务器一样添加多台服务器,从而能够提供更多的内存储存和更好的性能。 | 写操作性能下降:Redis集群适用于读多写少的应用,当进行大量的写操作时,性能会大幅度下降,并可能出现失败重试的情况。 |
高可用性:Redis集群能够有效地备份相关节点之间的数据,以应对一部分节点故障的情况,从而保护系统不受意外错误的影响。 | 操作复杂:Redis集群的操作相对于单机模式或其他结构(如主从结构)来说更为复杂,对于不太熟悉Redis的用户来说,操作可能比较困难。 |
分布式处理:Redis集群可以对大容量数据进行分布式处理,可有效提高数据处理的效率。 | 数据一致性问题:Redis集群通过异步复制数据,这可能导致数据在不同节点间存在不一致的情况。 |
故障自动failover:节点之间通过gossip协议交换状态信息,用投票机制完成Slave到Master的角色提升,降低运维成本,提高系统的扩展性和可用性。 | 资源隔离性较差:当多个业务使用同一套集群时,由于不能依据统计区分冷热数据,资源隔离性较差,容易出现互相影响的情况。 |
Key批量操作限制:Redis集群对于Key的批量操作有一定的限制,例如mget、mset等命令只支持相同slot值的key执行批量操作,不支持跨slot查询。 | |
不支持多数据库空间:单机Redis可以选择16个数据库,但集群模式下只能选择一个数据库,即db0。 |