专栏首页晨曦破晓の家Redis的各种数据类型实践--String字符串

Redis的各种数据类型实践--String字符串

Redis作为一款NoSQL内存数据库,其丰富的数据类型、简单易用的命令、单机可达10万的高并发(官方数据),从面世以来就深受广大用户的喜爱。Redis的五种数据类型,是我们学习Redis时的必修课,但是大多数人都只是去学它的命令、API,却不知道这些数据类型都能应用在哪些场景,那这些命令学起来也就会很快就忘,终究只是“纸上谈兵”。

用好这五种数据类型将给你的开发带来很大的便利,给你的程序带来很大的性能提升,同时这五种数据类型能玩出很多花样。

不过大多数同学,在实际的开发过程中,大多只用到了Redis五种数据类型中的1-3种,甚至有的只用过一种String类型。要么是业务场景简单用string足矣,要么就是根本不知道或想不到用别的数据类型更合适,那么即使是有些场景更适合用别的数据类型,可能自己也发觉不到。所以今天就来聊聊Redis的各种数据类型以及各自适用于什么场景。

Redis一共提供了5种数据类型,分别是String,Hash,List,Set,sorted set(Zset),下面就从各个数据类型的基本常用命令和使用场景分别说说吧。

String 字符串

字符串结构的常用命令

#字符串常用操作
SET  key  value //存入字符串键值对
MSET  key  value [key value ...] //批量存储字符串键值对
SETNX  key  value //存入一个不存在的字符串键值对
GET  key //获取一个字符串键值
MGET  key  [key ...] //批量获取字符串键值
DEL  key  [key ...] //删除一个键
EXPIRE  key  seconds //设置一个键的过期时间(秒)
#原子加减
INCR  key //将key中储存的数字值加1
DECR  key //将key中储存的数字值减1
INCRBY  key  increment //将key所储存的值加上increment
DECRBY  key  decrement //将key所储存的值减去decrement

这里列出了一些String常用命令,我们看一下这些String类型的这些命令可以应用到哪些场景

应用场景

1.单值缓存

即最简单的key-value的set和get,比如缓存个标识,开关等

image

2.对象缓存
#1
SET user:1  value(json串)
GET user:1
#2
MSET user:1:name 编程大道 user:1:sex 1
MGET user:1:name user:1:sex

image

第一种直接将对象转换成json串作为value存储到redis,这种获取对象就比较简单了,直接get key拿到value转成对象即可,但有个缺点就是如果你要是修改对象的某一个字段,也得把整个对象的json串拿出来反序列化成对象,这将带来不必要的网络开销(即便是redis存在内存中,但实际我们的应用服务器和redis是隔离的,网络传输的开销也不容小觑),同样,频繁的序列化反序列化也将会带来不小的性能开销,如果对于性能要求比较高的系统来说这将是一个灾难。

而第二种存储对象的方式则对于这种频繁修改对象某一个字段的场景就比较友好了,每个字段与值都是一个kv对,修改直接set k v覆盖就好了,但是存储多个字段时就没那么容易了,好在有mset批量操作的命令,网络开销由多次变为1次。 key命名也可以根据(对象):(ID):(字段)的结构进行命名

image

3.分布式锁

如下setnx命令是set if not exit的缩写,意思就是这个key不存在时才执行set。多个线程执行这条命令时只有一个线程会执行成功,则视为拿到锁。然后拿到锁的线程执行业务操作,执行完毕删除这个锁,释放锁。

#setnx key value
SETNX  product:10001  true   //返回1代表获取锁成功
SETNX  product:10001  true   //返回0代表获取锁失败
//执行业务操作
DEL  product:10001  //执行完业务释放锁

image

上述方式存在问题:程序意外终止可能会导致锁没办法释放,造成死锁。可以使用如下命令,既设置分布式锁又设置了key的过期时间

SET product:10001 true  ex  10  nx  //防止程序意外终止导致死锁

image

image

如上图我们可以看到ttl时间只剩5了到期就会自动释放

4.计数器

基于Redis原子自增命令incr可以实现诸如计数器的功能,我们都知道公众号文章,微博,博客都有一个阅读量的概念,我们就可以用这个计数器来实现,而且性能很高。

INCR article:readcount:{文章id}
GET article:readcount:{文章id}

image

5.Web集群session共享解决方案

系统集群部署情况下首先要考虑的问题就是session共享问题,我们可以通过将原本存储在内存中由tomcat管理的session转移到由Redis来存储,实现分布式session的功能。spring框架提供了session共享的解决方案,即spring session + redis实现分布式session。

6.分布式系统全局序列号

分布式系统中要保证全局序列号的唯一性,可以使用Redis来维护一个自增的序列。

通过如下命令从Redis获取自增ID:

#1
INCR orderId//INCR是一个原子自增命令

#2

INCRBY  orderId  1000//redis批量生成序列号提升性能

分布式系统环境下通过Redis保证ID的自增性和唯一性,通过该命令获取ID每次都要和Redis进行交互,如果业务量很大,那么这将会很频繁。

所以可以一次性获取一定量的ID保存在JVM内存中,用完了再从Redis获取。这样减少了频繁的网络开销,但是缺点是可能会丢失(浪费)一部分ID,因为获取后服务可能挂了还没用完的ID可能就浪费了(当然你可以使用一些手段去保证不浪费,但没必要,浪费一点也是无所谓的)。

方法2,每次获取1000个

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Redis的各种数据类型实践-Set

    Redis 的 Set 是 String 类型的无序集合。集合成员是唯一的,这就意味着集合中不能出现重复的数据。 Redis 中集合是通过哈希表实现的,所以添...

    用户4464623
  • Redis的各种数据类型实践-ZSet

    我们都知道微博热点,新闻热榜,投票排行榜等都有一个排名的概念,如下图百度热榜,展示的是实时的点击量比较高的新闻(假设这些新闻的ID为1001-1010),每个新...

    用户4464623
  • 搞懂 Redis 缓存穿透、击穿、雪崩

    如何有效的理解并且区分 Reids 穿透、击穿和雪崩之间的区别,一直以来都挺困扰我的。特别是穿透和击穿,过一段时间就稀里糊涂的分不清了。

    用户4464623
  • redis常用命令

    ​ -keys,flushall,flushdb,慢的lua脚本,mutil/exec,operate,big value

    GH
  • Redis基础你掌握多少了?来查漏补缺?

    Redis 是开源的内存中的数据结构存储系统,它可以用作数据库、缓存和消息中间件。它支持多种类型的数据结构,如 字符串strings, 散列 hashes, 列...

    猿哥
  • Redis基础你掌握多少了?来查漏补缺?

    Redis 是开源的内存中的数据结构存储系统,它可以用作数据库、缓存和消息中间件。它支持多种类型的数据结构,如 字符串strings, 散列 hashes, 列...

    用户3578099
  • JDK源码分析-Map

    Map 是一个接口,它表示一种“键-值(key-value)”映射的对象(Entry),其中键是不重复的(值可以重复),且最多映射到一个值(可以理解为“映射”或...

    WriteOnRead
  • Flutter 学习:ImageProvider工作流程和AssetImage 的自动分辨率适配原理

    最近碰到一个问题,自己使用 AssetBundle 加载 asset 图片去绘制的时候,不能自动加载到正确分辨率下的图片。于是好奇想一探究竟—— ImageAs...

    用户1468672
  • Redis入门之认识redis(一)

      1) NoSQL(NoSQL = Not Only SQL ),意即“不仅仅是SQL”,泛指非关系型的数据库。

    用户2417870
  • 手写JDK7-HashMap

    现在一般都JDK8了,为什么还要说JDK7呢。因为JDK7和JDK8的hashmap实现不一样,JDK7是用数组+链表实现的,而JDK8是红黑树。学习都是个慢慢...

    DH镔

扫码关注云+社区

领取腾讯云代金券