redis.config主要配置
操作
连接命令
目录文件
Redis客户端(client)命令
启动
前台启动
./redis-server
后台启动
将配置文件redis.conf,cp到/etc下
将配置文件daemonize设置为yes (是否连续启动)
./redis-server /etc/redis.conf
Linux环境下Redis允许外部访问
方式一:
注释掉配置文件中的bind 【ip address】
关闭Redis的服务保护模式
protected-mode no
方式二
将bind 的【ip address 】设置为0.0.0.0即所有人都可访问
PS:该模式下Redis的服务保护模式不需要关闭
保护模式下我们可以设置Redis的服务密码【Redis默认不需要密码】
远程服务器上运行命令
redis-cli -h host -p port -a password
参数说明:
- -h:用于指定远程 Redis 服务器的 IP 地址;
- -p:用于指定 Redis 远程服务器的端口号;
- -a:可选参数,若远程服务器设置了密码,则需要输入。
查看帮助
HELP option
redis基础
Redis架构
Redis体系架构主要分为两个部分:
- Redis服务端
- Redis客户端
redis概念
Redis 是一种键值(key-value)型的缓存型数据库,它将数据全部以键值对的形式存储在内存中。
key
type key 查看key的类型
key的命名规范
- key 取值不可以太长,否则会影响 value 的查找效率,并且浪费内存空间。
- key 取值也不能过短,否则会使得 key 可读性变差。
key过期时间
命令
数据类型
- EX seconds:设置指定的过期时间,以秒为单位;
- PX milliseconds:设置指定的过期时间,以毫秒为单位;
- NX:先判断 key 是否存在,如果 key 不存在,则设置 key 与 value;
- XX:先判断 key 是否存在,如果 key 存在,则重新设置 value。
string字符串
String 是 Redis 最基本的数据类型。字符串是一组字节,在 Redis 数据库中,字符串具有二进制安全(binary safe)特性,这意味着它的长度是已知的,不由任何其他终止字符决定的,一个字符串类型的值最多能够存储 512 MB 的内容。
操作数值
INCR命令
INCR 命令指对 value 数值做加 1 操作,其数值范围是 64 位的有符号整型(-9223372036854775808 至 9223372036854775807)。 如果 key 不存在,那么 Redis 将自动创建 key,并将 value 初始化为 1。
DECR命令
对数值执行减 1 操作
INCRBY命令
在原数的基础上进行指定数值的自增运算
DECRBY命令
在原数的基础上进行指定数值的自减运算
INCRBYFLOAT
string 中唯一操作浮点数的命令,浮点数可以为正数或者负数,从而实现对数值的加减操作。
hash散列
- hash 散列是由字符串类型的 field 和 value 组成的映射表,您可以把它理解成一个包含了多个键值对的集合。由于 Hash 类型具有上述特点,所以一般被用来存储对象 一个 Hash 中最多包含 2^32-1 个键值对。
因为Redis只为散列提供了用于执行加法操作的HINCRBY命令,但是没有为散列提供相应的用于执行减法操作的命令,所以如果用户需要对字段存储的整数值执行减法操作,就需要将一个负数增量传给HINCRBY命令,从而达到对值执行减法计算的目的。
List列表
-
Redis List 中的元素是字符串类型,其中的元素按照插入顺序进行排列,允许重复插入,最多可插入的元素个数为 2^32 -1 个(大约40亿个),您可以添加一个元素到列表的头部(左边)或者尾部(右边)。
-
相当于 Java 语言中的 LinkedList 结构,是一个链表而非数组,其插入、删除元素的时间复杂度为 O(1),但是查询速度欠佳,时间复杂度为 O(n)。
-
当列表中存储的元素较少时,Redis 会使用一块连续的内存来存储这些元素,这个连续的结构被称为 ziplist(压缩列表),它将所有的元素紧挨着一起存储。当数据量较大时,Redis 列表就会是用 quicklist(快速链表)存储元素。
-
压缩列表是 Redis 为节省内存而开发的,它是由一系列特殊编码的连续内存块组成的顺序型数据结构,一个压缩列表了可以包含任意多个节点,每个节点都可以保存一个字符数组或者整数值。
-
单独使用普通链表存储元素时,所需的空间较大,会造成存储空间的浪费。因此采用了链表和压缩列表相结合的方式
将多个 ziplist 使用双向指针串联起来,这样既能满足快速插入、删除的特性,又节省了一部分存储空间。
set集合
Redis Set 是一个字符串类型元素构成的无序集合。在 Redis 中,集合是通过哈希映射表实现的,所以无论是添加元素、删除元素,亦或是查找元素,它们的时间复杂度都为 O(1)。
zset有序集合
Redis zset 是一个字符串类型元素构成的有序集合,集合中的元素不仅具有唯一性,而且每个元素还会关联一 个 double 类型的分数,该分数允许重复。Redis 正是通过这个分数来为集合中的成员排序。
- 当 key 不存在时,将会创建一个新的有序集合,并把分数/成员(score/member)添加到有序集合中;当 key 存在时,但 key 并非 zset 类型,此时就不能完成添加成员的操作,同时会返回一个错误提示。\
注意:在有序集合中,成员是唯一存在的,但是分数(score)却可以重复。有序集合的最大的成员数为 2^32 - 1 (大约 40 多亿个)。
HyperLoglog基数统计
HyperLoglog 采用了一种基数估计算法,因此,最终得到的结果会存在一定范围的误差(标准误差为 0.81%)。每个 HyperLogLog key 只占用 12 KB 内存,所以理论上可以存储大约2^64
个值,而 set(集合)则是元素越多占用的内存就越多,两者形成了鲜明的对比 。
基数定义
基数定义:一个集合中不重复的元素个数就表示该集合的基数,比如集合 {1,2,3,1,2} ,它的基数集合为 {1,2,3} ,所以基数为 3。HyperLogLog 正是通过基数估计算法来统计输入元素的基数。
HyperLoglog 不会储存元素值本身,因此,它不能像 set 那样,可以返回具体的元素值。HyperLoglog 只记录元素的数量,并使用基数估计算法,快速地计算出集合的基数是多少。
PubSub发布订阅
Stream消息队列
一个 Stream 队列可以拥有多个消费组,每个消费组中又包含了多个消费者,组内消费者之间存在竞争关系。当某个消费者消费了一条消息时,同组消费者,都不会再次消费这条消息。被消费的消息 ID 会被放入等待处理的 Pending_ids 中。每消费完一条信息,消费组的游标就会向前移动一位,组内消费者就继续去争抢下消息。
每个Stream都有唯一的名称,它就是Redis的key,在我们首次使用xadd
指令追加消息时自动创建。
每个Stream都可以挂多个消费组,每个消费组会有个游标last_delivered_id
在Stream数组之上往前移动,表示当前消费组已经消费到哪条消息了。每个消费组都有一个Stream内唯一的名称,消费组不会自动创建,它需要单独的指令xgroup create
进行创建,需要指定从Stream的某个消息ID开始消费,这个ID用来初始化last_delivered_id
变量。
每个消费组(Consumer Group)的状态都是独立的,相互不受影响。也就是说同一份Stream内部的消息会被每个消费组都消费到。
同一个消费组(Consumer Group)可以挂接多个消费者(Consumer),这些消费者之间是竞争关系,任意一个消费者读取了消息都会使游标last_delivered_id
往前移动。每个消费者者有一个组内唯一名称。
消费者(Consumer)内部会有个状态变量pending_ids
,它记录了当前已经被客户端读取的消息,但是还没有ack。如果客户端没有ack,这个变量里面的消息ID会越来越多,一旦某个消息被ack,它就开始减少。这个pending_ids变量在Redis官方被称之为PEL
,也就是Pending Entries List
,这是一个很核心的数据结构,它用来确保客户端至少消费了消息一次,而不会在网络传输的中途丢失了没处理。
消息ID
消息ID的形式是timestampInMillis-sequence
,例如1527846880572-5
,它表示当前的消息在毫米时间戳1527846880572
时产生,并且是该毫秒内产生的第5条消息。消息ID可以由服务器自动生成,也可以由客户端自己指定,但是形式必须是整数-整数
,而且必须是后面加入的消息的ID要大于前面的消息ID。
xdel 删除消息,这里的删除仅仅是设置了标志位,不影响消息总长度
127.0.0.1:6379> xadd userQueue * username zz age 199 username ww age 213
"1659321282298-0"
127.0.0.1:6379> xadd userQueue * username zz age 199 name ww get 213
"1659321306547-0"
127.0.0.1:6379> xadd userQueue * username zz age 1992312 name ww get 21332
"1659321318797-0"
127.0.0.1:6379> xlen userQueue
(integer) 3
127.0.0.1:6379> xrange userQueue - + 2
(error) ERR syntax error
127.0.0.1:6379> xrange userQueue - +
1) 1) "1659321282298-0"
2) 1) "username"
2) "zz"
3) "age"
4) "199"
5) "username"
6) "ww"
7) "age"
8) "213"
2) 1) "1659321306547-0"
2) 1) "username"
2) "zz"
3) "age"
4) "199"
5) "name"
6) "ww"
7) "get"
8) "213"
3) 1) "1659321318797-0"
2) 1) "username"
2) "zz"
3) "age"
4) "1992312"
5) "name"
6) "ww"
7) "get"
8) "21332"
127.0.0.1:6379> xrange userQueue 1659321306547-0 +
1) 1) "1659321306547-0"
2) 1) "username"
2) "zz"
3) "age"
4) "199"
5) "name"
6) "ww"
7) "get"
8) "213"
2) 1) "1659321318797-0"
2) 1) "username"
2) "zz"
3) "age"
4) "1992312"
5) "name"
6) "ww"
7) "get"
8) "21332"
127.0.0.1:6379> xrange userQueue - 1659321306547-0
1) 1) "1659321282298-0"
2) 1) "username"
2) "zz"
3) "age"
4) "199"
5) "username"
6) "ww"
7) "age"
8) "213"
2) 1) "1659321306547-0"
2) 1) "username"
2) "zz"
3) "age"
4) "199"
5) "name"
6) "ww"
7) "get"
8) "213"
127.0.0.1:6379> del userQueue
(integer) 1
独立消费
消费组
流水线
流水线特性:这个特性允许客户端把任意多条Redis命令请求打包在一起,然后一次性地将它们全部发送给服务器,而服务器则会在流水线包含的所有命令请求都处理完毕之后,一次性地将它们的执行结果全部返回给客户端。
流水线只能保证多条命令会一起被发送至服务器,但它并不保证这些命令都会被服务器执行。
事务
所有数据操作命令都不会立即执行,而是会按顺序放入一个事务队列中,等待事务执行时再统一执行。
MULTI:开启事务
EXEC:执行事务
DISCARD:放弃事务
WATCH:对键进行监视
客户端可以通过执行WATCH命令,要求服务器对一个或多个数据库键进行监视,如果在客户端尝试执行事务之前,这些键的值发生了变化,那么服务器将拒绝执行客户端发送的事务,并向它返回一个空值:
UNWATCH:取消对键的监视
客户端可以通过执行UNWATCH命令,取消对所有键的监视:
RDB-AOF混合持久化模式
aof-use-rdb-preamble value
选项的值设置成了yes,那么Redis服务器在执行AOF重写操作时,就会像执行BGSAVE命令那样,根据数据库当前的状态生成出相应的RDB数据,并将这些数据写入新建的AOF文件中,至于那些在AOF重写开始之后执行的Redis命令,则会继续以协议文本的方式追加到新AOF文件的末尾,即已有的RDB数据的后面。
遇到的问题
NOAUTH Authentication required
redis代码操作
基础操作
redisTemplate.opsForValue(); // 操作字符串
redisTemplate.opsForHash(); // 操作hash
redisTemplate.opsForList(); // 操作list
redisTemplate.opsForSet(); // 操作set
redisTemplate.opsForZSet(); // 操作zset
redisTemplate.opsForHyperLogLog(); // 对HyperLogLogs(基数统计)类型的操作
redisTemplate.opsForGeo(); 对geospatial (地理位置)类型的操作
Boolean setBit(K key, long offset, boolean value); //对于BitMap的操作
Boolean getBit(K key, long offset); //对于BitMap的操作
redisTemplate.opsForStream(); //对于Stream的操作
思维导图
Lettuce
Redis高级客户端Lettuce详解(上)
developer.aliyun.com/article/917…
Redis高级客户端Lettuce详解(下)
developer.aliyun.com/article/917…
Redis缓存穿透、缓存雪崩、缓存击穿 www.bilibili.com/read/cv1006…