Redis场景总结

使用场景

在大型的秒杀库存扣减,app首页流量高峰,很容易将传统的关系型数据库(mysql,oracle等)给压垮。

还有很多没必要持久化的数据,比如说短信验证码,点赞数等。

分布式锁。

分布式缓存(会话共享)。

数据结构

redis的存储是以key-value的键值对的形式存储的,其中key都是String类型,value常见的就是以下的5种。

String

字符串类型,可以包含任何数据,最大可以是512MB,内部的实现结构和ArraList类似,采用内分配几余的形式,来减少内存的频繁分配(降低CPU压力)。

在创建字符串的时候,len 的长度就是capacity,当需要修改时,如果存储容量不够的话,就会进行扩容,当字符串的容量小于1mb时,就会执行加倍扩容,即扩容到2*capacity,当容量大于1MB时,每次多增加1MB。

复制代码
set name mengze --存放字符串键值对
mset name mengze age 18 --批量存放键值对
SETNX name mengze --如果不存在key为name,那么就设置value (分布式锁的原理)
get name -- 获取key
mget name age --批量获取key
DEL key --删除key
expire key 6 --设置过期时间,单位为秒
INCR key --将key中存储的数字加1
DECR key --将key中存储的数字减1
INCRBY key 2 --将key中存储的值都加上2
DECRBY key 2 --将key中存储的值都减去2

需要注意的是,尽量避免同时操作大批量的key,比如给所有的key设置过期时间,因为redis是单线程的,如果操作耗费太多时间,会造成redis的假死。(暂时不对外提供服务)

使用场景

1,不需要持久化的数据或者频繁更新的数据,比如验证码,点赞数。

2,对象缓存

可以通过序列化工具类,来缓存java对象,比如将某个对象序列化为json,需要用的时候再取出来,反序列化。常见的使用方式有mybatis二级缓存,接口级别缓存等等。

3,使用setnx来实现分布式锁,(使用分布式锁时一定要设置过期时间,防止不能释放锁,造成死锁)

4,可以用incr,decr来实现点赞数

5,分布式全局id

在一个大型的系统下,如果涉及到分库分表后,mysql 的自增id,肯定满足不了需要,如果用户量不大,可以每次从redis 这里通过自增获取id,但是如果用户量大,每次都拿肯定会给redis造成压力,可以一次取1000个,放本地缓存里,等用完了再去取。

Hash

是一个key-value的键值对,和iava里的hashMap相似,当数据量较小是采用的是ziphash (默认),当数据量较大时采用hashtable。

常用命令

复制代码
hset hash name mengze --设置值
hget hash name -- 获取值
hmset hash name mengze age 18 --批量设置
hmget hash name age --批量获取
hgetall hash --获取key的所有值
hkeys hash --获取hashmap中所有的key
hvals hash --获取hashmap中所有的value

应用场景

可以用于存储系统中对象的数据。

也可以用于做缓存,来解决数据一致性的问题(不推荐)。

List

redis的list为quickList (快速链表)即多个ziplist (压缩链表)组合起来的。

redis的list是按插入顺序排序的,可以添加的一个节点到链表的头部(头插)或者尾部(尾插),是一个双向链表,对两端的操作性能会比较高,对中间节点的操作性能相对来说较差(因为得通过指针对遍历对应的节点)。

常用指令

复制代码
rpush myList valu5e1 --向 ist 的头部 (右边)添加元素
rpush myList value2 value3 --向list的头部 (最右边)添加多个元素
lpop myList --将list的尾部(最左边)元素取出
rpop myList2 value1 --尾插

使用场景

可以实现栈和队列,需要注意的是,push和pop的操作是原子性的,所以操作redis的时候,直接用就行了,不要把list读出来,通过java修改,再放回去,这样不能保证数据一致性。 (先读先写或先读后写)。

Set

redis的set和list相似,只不过可以自动去重。 (java的set也可以自动去重)

当你需要存储一个没有重复数据的列表时就可以选择set,同时set也可以判断某个数据在不在集合里面。

set的底层结构是一个value为null的哈希表,也就意味着他的时间复杂度为0(1),也就意味着即使数据再多,查找的时间也是一样的。

使用场景

可以用来计算多个数据源的交集或并集。

SortedSet

和set很相似,sortedSet是一个有序不重复的列表。SortedSet里面的每个节点都关联了一个权重,用来排序。

(集合里的每个节点是唯一的,但是评分却可以是相同的),利用这个特性我们可以利用redis来实现排行榜。也可以很快速的获取到一个区间内的节点。

SortedSet的的底层是hash和跳表了一个很典型的数据结构,牺牲空间来换取时间) 。hash的作用是存储每个节点和权重,跳表的作用是用来快速获取一个区间里的节点。

redis常用的数据机构就是以上五种,还有一些不常用的。

使用场景

直播系统的实时排行榜

Geospatial

地理位置的缩写,可以表示一个区域的二维坐标,redis提供了经纬度设置,查询,范围查询,距离查询,经纬度hash等操作。

使用场景

可以用来计算距离最近的门店。

BloomFilter(布隆过滤器)

可能判断失误。因此他不适合零失误的场景布降过滤器是一段很长的二进制向量和一系列随机映射函数,用来快速检索一个元素是否在一个集合里。但是他的准确率不是百分之百,有可能判断失误。因此他不适合零失误的场景。

优点:

支持海量数据场景下,判断元素是否存在。

存储空间占用量小,不存储数据本身,存储的是hash值。

不存储数据本身,可以用来存储加密数据。

缺点:

不支持计数,同一个元素可以多次插入,而且效果是相同的。

使用场景

用来解决缓存穿透问题。

可以判断用户是否阅读过某篇文章,防止重复推送,比如说抖音。

相关推荐
weixin_307779134 分钟前
在 Microsoft Azure 上部署 ClickHouse 数据仓库:托管服务与自行部署的全面指南
开发语言·数据库·数据仓库·云计算·azure
六元七角八分14 分钟前
pom.xml
xml·数据库
Achou.Wang16 分钟前
源码分析 golang bigcache 高性能无 GC 开销的缓存设计实现
开发语言·缓存·golang
虚行24 分钟前
Mysql 数据同步中间件 对比
数据库·mysql·中间件
奥尔特星云大使25 分钟前
mysql读写分离中间件Atlas安装部署及使用
数据库·mysql·中间件·读写分离·atlas
牛马baby1 小时前
【mysql】in 用到索引了吗?
数据库·mysql·in
杀气丶1 小时前
L2JBR - 修复数据库编码为UTF8
数据库·sql·oracle
-Xie-1 小时前
Mysql杂志(三十)——索引失效情况
数据库·mysql
为java加瓦1 小时前
Lombok @Data 注解在 Spring Boot 项目中的深度应用与实践指南
java·开发语言·数据库
青山撞入怀11141 小时前
sql题目练习-子查询
java·数据库·sql