序号 | 内容 | 链接地址 |
---|---|---|
1 | Redis的基础知识、单机版安装、数据类型介绍(老版本) | https://blog.csdn.net/weixin_43246215/article/details/107474283 |
2 | Redis常用命令、配置文件介绍、数据持久化方式、集群搭建 (老版本) | https://blog.csdn.net/weixin_43246215/article/details/107947562 |
3 | Redis的五种常用数据类型、三种特殊数据类型详解 | https://blog.csdn.net/weixin_43246215/article/details/108041739 |
4 | Redis基本的事务操作以及使用Redis实现乐观锁 | https://blog.csdn.net/weixin_43246215/article/details/108045931 |
5 | 使用JedisAPI操作Redis以及Jedis实现Redis事务 | https://blog.csdn.net/weixin_43246215/article/details/108067542 |
6 | Redis的配置文件详解(中文) | https://blog.csdn.net/weixin_43246215/article/details/108068245 |
7 | Redis数据持久化的两种方式以及Redis实现订阅发布 | https://blog.csdn.net/weixin_43246215/article/details/108068797 |
8 | Redis的伪集群搭建以及主从复制原理 | https://blog.csdn.net/weixin_43246215/article/details/108069472 |
9 | Redis中哨兵(Sentinel)模式的使用以及相关配置介绍 | https://blog.csdn.net/weixin_43246215/article/details/108088179 |
10 | Redis中的缓存穿透、缓存击穿以及缓存雪崩(理论知识) | https://blog.csdn.net/weixin_43246215/article/details/108089026 |
11 | Spring整合Redis实现查询缓存以及同步缓存 | 待更新 |
12 | SpringBoot整合Redis以及自定义Redis Template | https://blog.csdn.net/weixin_43246215/article/details/108476328 |
13 | Redis常见面试题 | https://blog.csdn.net/weixin_43246215/article/details/108090095 |
14 | … | 待更新 |
Redis 是一个开源(BSD许可)的,内存中的数据结构存储系统,它可以用作数据库、缓存和消息中间件。
它支持多种类型的数据结构,如 字符串(strings),散列(hashes), 列表(lists),集合(sets),有序集合(sorted sets) 与范围查询, bitmaps, hyperloglogs 和 地理空间(geospatial) 索引半径查询。 Redis 内置了 复制(replication),LUA脚本(Lua scripting), LRU驱动事件(LRU eviction),事务(transactions) 和不同级别的 磁盘持久化(persistence), 并通过 Redis哨兵(Sentinel)和自动 分区(Cluster)提供高可用性(high availability)。
Redis的英文官网
Redis的中文官网
Redis的中文命令手册
本文主要介绍Redis五种常用的数据类型、三种特殊的数据类型的使用、应用场景。
Redis 字符串是字节序列。Redis 字符串是二进制安全的,这意味着他们有一个已知的长度没有任何特殊字符终止,所以你可以存储任何东西,512 M为上限,主要的还是操作键值对。
String的数据结构是简单的Key-Value模型,Value可以是字符串,也可以是数字。
格式:
set key value [expiration EX seconds|PX milliseconds] [NX|XX]
ex:秒级过期时间,nx:键不存在时才能设置成功,xx键存在时才能设置成功
(1)普通添加:set key value
(2)设置过期时间 setex:setex key seconds value
上图中:设置一个键为key1,值为hello,并且30秒后过期。
使用ttl命令
可以查看该键还有多少时间过期。
(3)不存在设置 setnx(set if not exist):setnx key value
如果key不存在,则创建一个key,如果key存在,则创建失败并返回0。
上图中,执行第一条命令时,由于key2不存在,所以就创建一个key2,执行第二句命令时,由于key2前面已经创建了,已经存在了,所以就创建失败,并且返回0。
setnx在分布式锁中经常使用到
127.0.0.1:6379> set name oldou
OK
127.0.0.1:6379> get name #获取name中的值
"oldou"
msetnx key1 value1 key2 value2…
同时设置多个值,如果其中有一个存在,那么就都创建失败。
要么一起成功,要么一起失败,这是一个原子性操作。
incr命令
让当前键值以 1 的数量递增,并返回递增后的值。相当于Java中的自增,每次使用改命令都能让变量自增1。
应用场景:(一般可用于设置浏览量、阅读量)
set user:1 {name:zhangsan,age:3}
user:{id}:{field}
如此设置在Redis中是完全OK的。
Redis 的哈希是键值对的集合。
Redis 的哈希值是字符串字段和字符串值之间的映射,因此它们被用来表示对象,还有用户信息之类的,经常变动的信息。
Hash更适合用于对象的存储,String更适合字符串存储。
hset命令
:存储一个哈希键值对的集合hget命令
:获取一个哈希键的值hmset
: 存储一个或多个哈希是键值对的集合hmget
: 获取多个指定的键的值hexists
: 判断哈希表中的字段名是否存在 如果存在返回 1 否则返回 0hdel
: 删除一个或多个字段hgetall
: 获取一个哈希是键值对的集合hvals
: 只返回字段值hkeys
: 只返回字段名hlen
: 返回 key 的 hash 的元素个数hincrby key field value
: 指定增量valuehsetnx key field value
: 如果该键不存在就创建,如果该键存在就创建失败。主要用于存储部分变更数据,比如存储用户信息等等
Redis 的链表是简单的字符串列表,排序插入顺序。您可以添加元素到 Redis 的列表的头部或尾部
Lpush:表示的是向链表的左添加,也就是向链表的头添加;
Rpush:表示的是向链表的右添加,也就是向链表的尾添加;
(1)lpush key value
: 向链表左侧添加—头插法
(2)rpush key value
: 向链表右侧添加–尾插法
(3)lpop key
: 从左边移出一个元素,就是从最左边的那个节点剔除掉。
(4)rpop key
: 从右边移出一个元素,就是从最右边的那个节点剔除掉。
(5)lrange key start end lrange
: 命令将返回索引从 start 到 stop 之间的所有元素。Redis 的列表起始索引为 0。
如果是要获取全部的元素:lrange key 0 -1
(6)llen key
: 返回链表中元素的个数 相当于关系型数据库中 select count(*)
(7)lindex key indexnumber
:lindex 命令用来返回指定索引的元素,索引从 0 开始,如果是负数表示从右边开始计算的索引,最右边元素的索引是-1。如果要将列表类型当做数组来用,lindex 命令是必不可少的。
(8)lset key indexnumber value
: 是另一个通过索引操作列表的命令,它会将索引为 index的元素赋值为 value,原来的值会被覆盖。如果该列表不存在就会报错。所以使用这个命令之前先使用exists判断一下。
(9)lrem key count value
: 移除key链表中count个元素的value值,精确匹配,如果链表中可以有多个重复的值,这里的count指的是可以删除多个相同key的值。
(10)ltrim list startIndex endIndex
:通过下标截取指定的长度,这个时候list已经改变了,只剩下截断的元素。
(11)rpoplpush source destination
:移除当前的source链表中的最后一个元素,并且将该元素移动到destination链表当中。
(12)linsert key BEFORE|AFTER pivot value
:在key列表的pivot元素的前/后面插入元素value。
小结:
实际上list是一个链表,before node after,left ,right都可以插入值;
如果key不存在,就创建新的链表;
如果key存在就创建新的值;
如果移除了所有的值,空链表,也就代表不存在;
在两边插入或者改动值,效率最高,中间元素相对来说效率会低一点。
Redis 的集合是字符串的无序集合。
在Set集合当中,是不允许有重复的。
set是通过hash table实现的,可以进行添加、删除和查找。对集合我们可以取并集,交集,差集.
sadd key value
:添加一个 string 元素到,key 对应的 set 集合中, 成功返回 1,如果元素已经在集合中返回 0scard key
: 返回 set 的元素个数,如果 set 是空或者 key 不存在返回 0smembers key
: 返回 key 对应 set 的所有元素,结果是无序的sismember key value
: 判断 value 是否在 set 中,存在返回 1,0 表示不存在或者 key 不存在srem key value
: 从 key 对应 set 中移除给定元素,成功返回 1,如果 value 在集合中不存在或者 key 不存在返回 0srandmember key nums
: 从key集合中随机抽取nums个元素。spop key
:随机删除一些key集合中的元素。smove source destination member
:将原集合source中的member元素移动到destination集合中。sdiff key1 key2
:取出key1中与key2集合的不同元素,差集sinter key1 key2
:取key1与key2两个集合中相同的元素,交集sunion key1 key2
:将key1与key2两个集合中的元素合在一起,并集Redis 的有序集合类似于 Redis 的集合,字符串不重复的集合。
(1)zadd key score value
: 将一个或多个 value 及其 socre 加入到 set 中
(2)zrange key start end
:0 和-1 表示从索引为 0 的元素到最后一个元素(同 LRANGE 命令相似)
(3)zrange key 0 -1 withscores
也可以连同 score 一块输出,使用 WITHSCORES 参数
(4)zremrangebyscore key start end
:可用于范围删除操作
(5)zrangebyscore key min max
: 升序排序操作,将key按最小值到最大值进行输出。
zrevrange salary 0 -1
:这个是倒序全部输出
以上是从小到大排序,也就是升序排序。
(6)zrevrangebyscore key max min
:倒序排序操作,将key按照从大到小排序输出
(6)zrem key value
: 删除指定的元素
(7)zcard key
:获取有序集合中的个数
(8)zcount key min max
: 获取指定区间的成员数量
本次介绍的三种特殊类型为:
我们日常生活中的定位、查看附近的人、朋友的定位、打车距离计算等等,基本上都是使用Geospatial 。
Redis的Geo在Redis3.2版本就推出了这个功能,这个功能可以推算出地理位置的信息,两地之间的距离,方圆几里的人。
链接地址点这里
它主要有以下六个命令:
geoadd命令
:将指定的地理空间位置(纬度、经度、名称)添加到指定的key中。geoadd key 经度 纬度 地理位置
(error) ERR invalid longitude,latitude pair 39.900000,116.400000
同时,这个命令还可以添加多个元素,例如:
geoadd china:city 116.40 39.90 beijing 121.47 32.23 shanghai
规则:两级(南极北极)是无法直接添加的,一般会下载城市数据,直接通过Java程序一次性导入。
(2)geopos命令
:从key里返回所有给定位置元素的位置(经度和纬度)。
格式:geopos key member
例如:geopos china:city beijing
返回值:GEOPOS 命令返回一个数组, 数组中的每个项都由两个元素组成: 第一个元素为给定位置元素的经度, 而第二个元素则为给定位置元素的纬度。
当给定的元素不存在时,对应的数组项为空值。
(3)geodist命令
:返回两个给定位置之间的直线距离,如果两个位置之间的其中一个不存在,那么命令就返回空值。
格式:geodist key member1 member2 [unit]
指定单位的参数 unit 必须是以下单位的其中一个:
m 表示单位为米。
km 表示单位为千米。
mi 表示单位为英里。
ft 表示单位为英尺。
如果用户没有显式地指定单位参数, 那么 GEODIST 默认使用米作为单位。
GEODIST 命令在计算距离时会假设地球为完美的球形, 在极限情况下, 这一假设最大会造成 0.5% 的误差。
(4)georadius命令
:以给定的经纬度为中心,找出某一半径内的元素。
以给定的经纬度为中心,返回键包含的位置元素当中,与中心的距离不超过给定最大距离的所有位置元素。
格式:georadius key longitude latitude radius m|km|ft|mi
例如: georadius china:city 110 23 1000 km
key为键,longitude、latitude表示当前位置的经纬度,radius表示搜索半径,m|km|ft|mi表示单位。
上图的代码解释:
以110 23为经纬度查询方圆1000km内的城市。前提是所有的数据录入了china:city中。
其余参数解释:
georadius key longitude latitude radius m|km|ft|mi [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count] [ASC|DESC] [STORE k]
在给定以下可选项时, 命令会返回额外的信息:
WITHDIST
: 在返回位置元素的同时, 将位置元素与中心之间的距离也一并返回。 距离的单位和用户给定的范围单位保持一致。显示到中间距离的位置。
WITHCOORD
: 将位置元素的经度和维度也一并返回。显示他人的定位信息。
WITHHASH
: 以 52 位有符号整数的形式, 返回位置元素经过原始 geohash 编码的有序集合分值。 这个选项主要用于底层应用或者调试, 实际中的作用并不大。
命令默认返回未排序的位置元素。 通过以下两个参数, 用户可以指定被返回位置元素的排序方式:
ASC
: 根据中心的位置, 按照从近到远的方式返回位置元素。
DESC
: 根据中心的位置, 按照从远到近的方式返回位置元素。
在默认情况下, GEORADIUS 命令会返回所有匹配的位置元素。 虽然用户可以使用COUNT
选项去获取前 N 个匹配元素, 但是因为命令在内部可能会需要对所有被匹配的元素进行处理, 所以在对一个非常大的区域进行搜索时, 即使只使用 COUNT 选项去获取少量元素, 命令的执行速度也可能会非常慢。 但是从另一方面来说, 使用 COUNT 选项去减少需要返回的元素数量, 对于减少带宽来说仍然是非常有用的。
获得指定的人数:2人
应用场景:附近的人。。
georadiusbymember命令
:找出位于指定范围内的元素,中心点是由给定的位置元素决定。georadiusbymember key member radius m|km|ft|mi
georadiusbymember china:city shanghai 1000 km
geohash命令
:返回一个或多个位置元素的Geohash字符串。GEO底层的实现原理其实就是Zset,我们可以使用Zset命令来操作GEO。
什么是基数?
一个可重复集合内不重复元素的个数就是基数。
简介
Redis 2.8.9版本就更新了Hyperloglog数据结构。
Redis Hyperloglog基数统计的算法。
优点:占用的内存是固定的,2^64不同元素的技术,只需要费12KB内存。如果要从内存角度来比较的话,Hyperloglog是首选。
举例:网页的UV(一个人访问一个网站多次,但是还是算作一个人)
传统的方式:使用set保护用户的ID,然后就可以统计set中的元素数量作为标准判断,这个方式如果保存大量的用户id,就会比较麻烦。
我们的目的是为了计数,而不是存储用户id。
pfadd key member1 member2 ....
:添加一个或者多个元素pfcount key
:统计key集合中基数的个数pfmerge newKey key1 key2 ...
:合并key1和key2中的元素,并且剔除其中重复的元素,产生新的集合newKey。如果允许容错,那么一定要使用Hyperloglog;
如果不允许容错,就使用set或者自己的数据类型即可。
(容错就是当由于种种原因在系统中出现了数据、文件损坏或丢失时,系统能够自动将这些损坏或丢失的文件和数据恢复到发生事故以前的状态,使系统能够连续正常运行的一种技术,很简单的意思)
(1)setbit key offset value
:value只能是0或者1,如下例子所示:
使用bitmap来记录周一到周日的打卡。
上图中的offeset表示周几,value的0表示未打卡,1表示打开成功。
周一0:1,周二1:0,周三2:1,周四3:1,…
(2)getbit key offset
:获取key中的offset值,查看某一天是否打卡
以上表示的是查看周四是否打卡,周日是否打卡。
(3)bitcount key
:统计操作,统计打开的天数,相当于统计sign中value为1的元素个数
统计用户信息、活跃、不活跃、登录、未登录、打卡等等… 两个状态的都可以使用Bitmap。
在生活或者开发中都有十分多的应用场景。
1、Redis 的数据类型有哪些?
Redis支持五种数据类型:String(字符串)、hash(哈希)、list(列表)、set(集合)以及zsetsorted set(有序集合)。
我们实际项目中比较常用的是String和hash,如果你是Redis的中高级用户,还需要加上以下几种数据类型,分别是:HyperLogLog、Geo、Pub/Sub。
如果你玩过Redis Module,像BloomFilter、RedisSearch、Redis-ML,,等等,是加分项。
2、一个字符串类型的值能存储最大容量是多少?
一个字符串类型的值能存储的最大容量为512M。
3、Redis key 的过期时间和永久有效分别怎么设置?
使用expire命令对key的过期时间进行设置;
使用persist命令对key永久有效进行设置;
4、一个 Redis 实例最多能存放多少的 keys?List、Set、Sorted Set他们最多能存放多少元素?
理论上Redis可以处理多达232个keys,并且在实际中进行了测试,每个实例至少存放了2亿5千万的keys。
任何list、set和sorted set都可以放232个元素,换句话说,Redis的存储极限是系统中的可用内存值。
5、Redis 最适合的场景?
6、假如 Redis 里面有 1 亿个 key,其中有 10w 个 key 是以某个固定的已知的前缀开头的,如果将它们全部找出来?
使用keys指令可以扫出指定模式的key列表。
7、如果这个Redis正在给线上的业务提供服务,那使用keys指令会有什么问题?
这个时候就要回答:Redis是单线程的,keys指令会导致线程阻塞一段时间,线上服务会停顿,知道指令执行完毕,服务才能恢复。这个时候可以使用scan指令,scan指令可以无阻塞的提取指令模式的key列表,但是会有一定的重复概率,在客户端做一次去重就可以了,但是整体所花费的时间会比直接用keys指令长。
8、如果有大量的 key 需要设置同一时间过期,一般需要注意什么?
如果大量的key过期时间设置过于集中,那么到过期的那个时间点,Redis可能会出现短暂的卡顿现象。一般需要在时间上加一个随机值,使得过期时间分散一点。
9、使用过 Redis 做异步队列么,你是怎么用的?
一般使用list结构作为队列,rpush生产消息,lpop消费消息。
当lpop没有消息的时候,要适当sleep一会儿再重试。
追问:可不可以不使用sleep呢?
list还有个指令叫blpop,在没有消息的时候,它会阻塞住,直到消息到来。
再追问:能不能生产一次,消费多次呢?
使用pub/sub主题订阅者模式,可以使用1:N的消息队列。
再问:pub/sub有什么缺点?
在消费者下线的情况下,生产的消息会丢失,解决这样的问题得使用专业的消息队列,如RabbitMQ等。
Redis如何实现延时队列呢?
使用sortedset,拿时间戳作为score,消息内容作为key调用zadd来生产消息,消费者用zrangbyscore指令获取N秒之前的数据轮询进行处理。
10、使用过 Redis 分布式锁么,它是什么回事?
先拿setnx来争抢锁,抢到之后再用expire给锁加一个过期时间防止锁忘记了释放。
问:如果在setnx之后执行expire之前进程意外crash或者要重启维护了,那会怎么样?
这个时候确实锁会永远得不到释放了,但是set指令有个非常复杂的参数是可以同时把setnx和expire合成一条指令来用的。
学习Redis建议看官网的文档进行学习,Redis还有许多的命令未介绍出来,如果在工作中使用到了,可以去Redis官方文档中查看,这里介绍一个Redis的中文命令手册点击即达。
创作不易,如果觉得对你有帮助,可以点个赞支持一下哈。