Redis简介

Redis(Remote dictionary server) 是一款高性能的开源非关系型缓存数据库,Redis使用C语言编写,支持多种类型的数据结构,如字符串,字典,列表,集合,有序集合与范围查询, bitmaps,hyperloglogs 和 地理空间(geospatial)索引半径查询。Redis 内置了 复制,LUA脚本,LRU驱动事件,事务和不同级别的磁盘持久化,并通过 Redis哨兵和自动分区提供高可用性。

String类型基本命令

新建字符串的格式为 SET key value,这是最简单的形式,还可以在后面添加一些其他的参数,我们后面再讲

查看字符串,直接GET key就可以啦

对字符串进行追加,用APPEND key content

看到这里可能就会有小伙伴问了,如果我想一次性设置多个字符串应该怎么办呢?当然使用MSET命令了呀,这个命令相当于把多个SET命令合并到一起了

有了批量设置,那批量读取呢?可能有的读者已经想到了,没错,批量读取的命令就是MGET

除了基本的添加和查询,redis字符串还有很多高级的功能

为键值对设置过期时间,我们可以通过EXPIRE命令为一个已经存在的键设置过期时间

在这里我先通过SET设置了一个键值对,然后通过EXPIRE操作为kkk这个键设置了三秒的过期时间,三秒之内可以查询到结果,但是三秒之后就查询不到了

还有一个命令是SETEX(set and expire),基本格式是SETEX key second value, 其中的second就是有效时间,过了这个有效时间这个key就被删除了(msetnx的作用就不用我说了吧)

可以看到我为kkk设置了三秒的过期时间,在设置完的三秒内是可以查询到相应的值,过了三秒之后就查不到了。

我们还可以通过PSETEX命令完成和SETEX命令一样的功能,只不过setex是以秒为单位,而PSETEX是以毫秒为单位。

设置锁,在redis中可以通过SETNX命令来设置锁,如果设置成功之后,再次执行这个命令则无法成功,SETNX(set if not exist),只有当不存在这个键的时候才会成功。

我们可以看到,我们第一次执行这个命令的时候返回了1(代表成功),第二次执行却返回了(0),代表失败,因为第二次执行的时候这个键已经存在了,则必然失败。

那有的小伙伴又会问了,如果已经通过SETNX设置了键值对之后,我还想重新设置这个键的值该怎么办呢?还记得我们刚刚说的过期时间吗,我们可以通过EXPIRE为他设定一个过期时间,当然还有另外一个做法

我们可以通过对SET操作加上其他命令行参数就可以啦, 上面图里的EX表示设置过期时间,5就表示五秒后过期,NX表示如果这个键不存在才生效,当然EX和NX这两个参数都是可以单独使用的

对一个字符串的一定范围内进行设置可以通过SETRANGE进行实现,

这里需要注意的是不管我们想设置的字符串长度为多少,都是可以成功的,如果超出了原字符串的长度会自动扩容

我们可以通过GETRANGE命令获取对应位置上的子串,这里可以把起始范围设置为负数,表示倒数第几个值

在Redis的字符串中,如果字符串中的字符全是整数,则可以对这个“字符串”(其实是个整数啦)进行简单的自增自减操作,自增自减操作的命令是INCR和DECR,我们可以看到下图中我们给test赋值为996,对他的自增自减操作可以成功

如果是小数类型就不可以了

那如果我想每次自增100该怎么办呢?执行incr执行100次?当然不会这么麻烦啦,我们以自增操作来演示一下,通过INCRBY命令 ,我们可以在后面设置一个步长就可以了,DECRBY操作也是一样的,大家可以自己去试一试。

但我如果我就想对小数类型进行自增操作怎么办?我们可以使用INCRBYFLOAT命令就可以了,这里需要注意的是并不存在DECRBYFLOAT

一些不太常见的命令

BITCOUNT命令可以用来统计字符串中字符二进制表示中1的个数

redis这个字符串的二进制表示为01110010 01100101 01100100 01101001 01110011,一共有20个1,通过BITCOUNT就可以将其统计出来

GETBIT命令可以获取对应偏移量上的比特值,a的二进制表示是01100001

SETBIT可以设置对应偏移量上的比特值,改变这个比特之后原来的值也会发生相应变化

STRALOG,对字符串执行某些特定算法,暂时支持获取最长公共子序列,注意是子序列而不是子串,子串是在原串中连续存在的而子序列不需要连续存在

SETLEN命令获取字符串长度

以上包括了绝大多数的字符串类型的命令了,别问我为什么不是全部,问就是有几个我自己也没搞懂。。

如果想更全面的了解,可以去下面两个网址了解

英文官方文档https://redis.io/commands#string

中文文档http://www.redis.cn/commands.html#string

String底层结构

Redis中最常用的数据类型非String莫属,网传大部分程序员也只会用Redis的String类型。我们上面说到Redis是用C语言写的,但是Redis中的String却不是直接用我们常见的C语言字符类型数组写的,这是为什么呢?我们就一起深入源码看一下String类型,首先先看String类型结构的示意图

Redis中String类型是实现依赖于一种名为sds的自定义结构,sds中包含了free(当前可用空间大小),len(当前存储字符串长度),buf[] (存储的字符串内容),下面是sds的源码实现

源码中sds结构中共分为五个细分类型。之所以有5种,是为了能让不同长度的字符串可以使用不同大小的header。我们可以看到不同sds中len和alloc(free)的类型是不一样的,他们也对应着不同的长度,而结构体中的flags字段就记录着header的类型。

通过对不同长度的字符串分配范围不同的长度,从而最大化的节省空间,可见Redis团队对性能的极致追求。

使用sds有什么好处?

1.减少内存分配次数

我们知道Redis是一种直接使用内存的数据库,数据保存在内存当中,当我们对一个字符串类型进行追加的时候,可能会发生两种情况:①当前剩余空间(free)足够容纳追加内容时,我们就不需要再去分配内存空间,这样可以减少内存分配次数。②当前剩余空间不足以容纳追加内容,我们需要重新为其申请内存空间。

2.惰性释放内存空间

当我们截断字符串时,Redis会把截断部分置空,只保留剩余部分,且不立即释放截断部分的内存空间,这样做的好处就是当下次再对这个字符串追加内容的时候,如果当前剩余空间足以容纳追加内容时,就不需要再去重新申请空间,避免了频繁的内存申请。暂时用不上的空间可以被Redis定时删除或者惰性删除。

3.防止缓冲区溢出

在C语言中如果我们对一个字符串数组进行拼接时,如果没有把握'\0'的位置,则肯有可能造成缓冲区溢出的问题,但是在redis中我们通过len的长度来进行控制,很好地避免了这一点

4.二进制安全

在C语言中通过判断当前字符是否为'\0'来确定字符串是否结束,而在sds结构中,只要遍历长度没有达到len,即使遇到'\0',也不会认为字符串结束。根据这一点,我们就可以使用Redis缓存诸如图像、音频、压缩文件的二进制形式。

深挖Redis字符串

上面的SDS只是字符串类型中存储字符串内容的结构,Redis中的字符串分为两种存储方式,分别是embstr和raw,当字符串长度特别短的时候,Redis使用embstr来存储字符串,而当字符串长度超过44的时候,就需要用raw来存储,下面是他们的字符串完整结构的示意图

所有redis对象都会存在一种对象头的结构,这个对象头记录了数据的type(类型),encoding(编码方式),lru(用于lru相关缓存淘汰策略机制的时间戳),refcount(引用次数)和ptr(指向sds的指针)

embstr的存储方式是将RedisObject对象头和SDS结构放在内存中连续的空间位置,使用malloc方法一次分配,而raw需要两次malloc,分别分配对象头和SDS的空间。

为了能分配容纳一个完整的embstr对象,jemalloc(facebook提出的内存分配方案)最少会分配32字节,如果字符串再长一点,那就是64字节的空间,而embstr中会有一些固定字段使用19字节的空间,embstr是以NULL结尾的,占用一个字节,所以embstr只能存储44字节长度的字符串,如果超过44字节,Redis会使用raw进行存储。

字符串扩容策略

如果当前字符串结构小于1MB,扩容会采取加倍策略,若当前字符串长度超过1MB,为了避免加背后的空余空间造成空间浪费,每次至多分配1MB

参考链接

https://mp.weixin.qq.com/s/vXBFscXqDcXS_VaIERplMQ

https://github.com/AobingJava/JavaFamily

https://blog.csdn.net/codejas/article/details/88582831

《Redis深度历险》

好了,以上就是本期关于Redis里面字符串类型的内容了,基本也算是挺全的了,下个周打算写一篇volatile关键字的和一篇RedisHash类型的文章,大家有什么想看的可以后台告诉我,我会尽力给大家做。

我是星海,因为我不会,所以我才会,我们下次再见

扫码关注我们

微信号|码外狂徒

redis 自增_坏了,Redis的字符串类型竟然被张三学明白了?相关推荐

  1. netcore redis 存储集合_.net core redis的全套操作

    摘要: 发布订阅 2.在.netcore中的调用订阅:redisManager.Subscribe("dylan",(channel,value)=>{Console.Wri ...

  2. redis是什么_什么是Redis?为什么我们要用Redis?

    前言 当结束Java和数据库的学习以后,你就会接触到Redis这个词,我第一次听到的时候脑海里就会浮现这两个问题: 什么是Redis?为什么我们要用Redis? 我了解完以后,写出来帮助大家能够更快的 ...

  3. 安装redis并开启_如何安装Redis,以及对Redis配置文件的更改和测试

    Redis的安装 1.下载redis包文件https://redis.io/ 2. 上传安装包(将其压缩包拖入Linux中所需上传的目录下) 3.解压安装包 tar -zxvf redis-5.0.5 ...

  4. redis stream持久化_[灌水] Redis 的持久化

    关于 Redis 的 Persistence, 最好的入门材料应该是: 它有两种形式,AOF 和 RDB:RDB 相对来说是一个数据库的"snapshot",通过 SAVE 或者 ...

  5. java redis使用卡死_注意!Redis使用不当可能导致应用卡死

    点击上方"Java知音",选择"置顶公众号" 技术文章第一时间送达! 作者:小木 my.oschina.net/xiaomu0082/blog/2990388 ...

  6. redis 公网 安全_最安全redis公网访问

    {"moduleinfo":{"card_count":[{"count_phone":1,"count":1}],&q ...

  7. java token redis生成算法_如何访问 Redis 中的海量数据,服务才不会挂掉?

    来源:www.toutiao.com/i6697540366528152077 一.前言 有时候我们需要知道线上的Redis的使用情况,尤其需要知道一些前缀的key值,让我们怎么去查看呢?并且通常情况 ...

  8. java redis快速入门_快速入门Redis系列(3)——Redis的JavaAPI操作(附带练习)

    作为快速入门Redis系列的第三篇博客,本篇为大家带来的是Redis的JavaAPI操作. 码字不易,先赞后看! Redis的JavaAPI操作 看完了上一篇博客,相信大家对于Redis的数据类型有了 ...

  9. 《Redis入门指南(第2版)》一3.2 字符串类型

    本节书摘来异步社区<Redis入门指南(第2版)>一书中的第3章,第3.2节,作者: 李子骅 责编: 杨海玲,更多章节内容可以访问云栖社区"异步社区"公众号查看. 3. ...

最新文章

  1. 2022-2028年中国香精香料行业投资分析及前景预测报告
  2. 14.7倍推理加速、18.9倍存储节省!北航、商汤、UCSD提出首个点云二值网络 | ICLR 2021...
  3. 基于RYU应用开发之负载均衡(源码开放)
  4. python软件怎么用-如何使用Python自动控制windows桌面
  5. Java中异常的分类
  6. 肖仰华:基于知识图谱的用户理解
  7. e站app改内置hosts_米家踢脚线电暖器E评测:符合现代家居审美 全屋取暖“小钢炮”...
  8. Haproxy 管控台介绍
  9. vue实现搜索框记录搜索历史_云开发版的微信商城小程序第四章,首页自定义搜索框的实现...
  10. 苹果发布iOS 12.4首个测试版 苹果信用卡即将来袭
  11. createwindow 和 dialogbox的区别
  12. 用简单直白的方式讲解A星寻路算法原理
  13. html5植物生长,关于植物生长的知识
  14. (转)高频交易的外部网络连接技术
  15. 单点登录原理与代码实现
  16. 迷宫算法,求解所有路径(DFS),(bug找了好久 )
  17. uview框架u-form表单校验,rules校验对象中对象的值(解决 当form属性嵌套对象时未取到值的问题)
  18. matlab的比较器模块,simulink中的比较器
  19. 元宇宙:人类叙事的下一个100年
  20. Making Startup Magic

热门文章

  1. LOGO设计没有灵感?5种方法来寻找标志设计的灵感和想法
  2. php 去除小数点后,php-删除两位小数点后的数字,而不舍入该值
  3. python输入正整数n、求n以内能被17整除的最大正整数_求100之内自然数中最大的能被17整除的数资料...
  4. 牛客网编程题01--计算字符串最后一串单词的长度,单词以空格隔开,字符串小于5000
  5. 图解Http学习第二章
  6. asp.net 添加权限
  7. 分级时间轮优化普通时间轮定时器
  8. android string拼接字符串_String对象的存储、拼接和比较
  9. python秒转换成小时分钟秒_仅需1秒!搞定100万行数据:超强Python数据分析利器...
  10. Sklearn之Ensemble 估计器