Redis的String探索之路
String是redis最基本的类型,键值对(Key : Value 形式),Redis 的 String 可以包含任何数据,最大能存储 512 MB。(一个键最大能存储 512MB)
Redis 的字符串是动态字符串,是可以修改的字符串哦 ^_^,采用预分配冗余空间的方式来减少内存的频繁分配。党字符串长度小于 1M 时,扩容都是加倍当前的空间,当超过 1M 在扩容时只会多扩 1M的空间大小。
注意:
- 字符串在长度小于 1M 之前,扩容空间采用加倍策略,也就是保留 100% 的冗余空间。
- 当长度超过 1M 之后,为了避免加倍后的冗余空间过大而导致浪费,每次扩容只会多分配 1M 大小的冗余空间。
String 内部分配结构
String 内部为当前字符串实际分配的空间 capacity 一般要高于实际字符串长度 len。
set key value [EX seconds|PX milliseconds] [NX|XX] [KEEPTTL]
- EX seconds: 设置键的过期时间为多少秒。
- set key value Ex seconds <=> setex key seconds value
set name xiaomo ex 2 = setex name 2 xiaomo
- PX milliseconds: 设置键的过期时间为 多少毫秒。
set key value ex milliseconds
<=> psetex key millseconds valueNX
:在键不存在时, 才对键进行设置操作。- set key vlaue ex <=>
setnx key value
XX
:在键已经存在时, 才对键进行设置操作。
返回值:set命令在设置操作成功完成时才返回 OK 。
如果设置参数 nx ,当值不存在时返回 OK,存在返回 nil 。
Redis 的字符串叫「SDS」— Simple Dynamic String,
它的结构是一个带长度信息的字节数组。
struct SDS<T> {
T capacity; // 数组容量
T len; // 数组长度
byte flags; // 特殊标识位,不理睬它
byte[] content; // 数组内容
}
Redis 的字符串有两种存储方式,embstr 和 raw。
在长度特别短时,使用 emb
形式存储 (embeded),当长度超过 44 字节时,使用 raw
形式存储。
在Redis 对象头结构体,所有的 Redis 对象都有下面的这个结构头:
struct RedisObject {
int4 type; // 4bits
int4 encoding; // 4bits
int24 lru; // 24bits
int32 refcount; // 4bytes
void *ptr; // 8bytes,64-bit system
} robj;
4b + 4b + 24b + 4B + 8B = 16B
每个对象都有个引用计数,当引用计数为零时,对象就会被销毁,内存被回收。一个 RedisObject 对象头需要占据 16 字节的存储空间。
SDS 内部结构如下:
struct SDS {
int8 capacity; // 1byte
int8 len; // 1byte
int8 flags; // 1byte
byte[] content; // 内联数组,长度为 capacity(默认开辟的空间)
}
在 SDS 结构体的大小,在字符串比较小时,SDS 对象头的大小是content+3
,至少是 3。意味着分配一个字符串的最小空间占用为 19 字节 (内容为空)。
SDS 结构体中的 content
中的字符串是以字节\0
结尾的字符串,之所以多出这样一个字节,是为了便于直接使用 glibc
的字符串处理函数,以及为了便于字符串的调试打印输出。
- 当内存分配器分配了 64 空间时,那这个字符串的长度(内容)最大可以是多少呢?
64 - 19 - 1 = 44(字节)
127.0.0.1:> set content aaaabbbbccccddddeeeeffffgggghhhhiiiijjjjkkkk
OK
127.0.0.1:> debug object content
Value at:0x7f4f4f0c3a40 refcount: encoding:embstr serializedlength: lru: lru_seconds_idle:
127.0.0.1:> append content l
(integer)
127.0.0.1:> debug object content
Value at:0x7f4f4f0adc20 refcount: encoding:raw serializedlength: lru: lru_seconds_idle:
(1)可以用来计数
如果 value 值是一个整数,还可以对它进行自增(自减)操作。
1.商品数量变化
2.博客论坛帖子点赞数目
3.文章帖子收藏用户数
4.文章帖子转发数
5.用户留言数目
····
基本跟数量变化的都可以使用上呀 ~
但是要注意的一点是:自增是有范围的,它的范围是 signed long long 的最大和最小值,超过了这个值,Redis 会报错。
long long (__int64)
范围:-922 3372 0368 5477 5808 ~ 922 3372 0368 5477 5807 (922*10^16)
127.0.0.1:6379> set age 9223372036854775807
OK
127.0.0.1:6379> get age
""
127.0.0.1:6379> incr age
(error) ERR increment or decrement would overflow
127.0.0.1:6379> set age -9223372036854775808
OK
127.0.0.1:6379> get age
"-9223372036854775808"
127.0.0.1:6379> incrby age -1
(error) ERR increment or decrement would overflow
(2)可以用来限流
比如在某些火爆新品上架的时候,商家上架的货都是有一定的数量的。同时,会设置在一段时间内销售商品。这个时候需要用 Redis 来做一些限流操作,限制一个操作可以被执行的速率,让每个商品的最大请求访问限制在一定范围内(设置键的生存时间)。
(3)二进制 — 位图使用(bitmap)
1. 统计 :任意用户在任意时间窗口登录天数(setbit、bitcount)
2.送礼品:在活跃期间段的用户,送礼品盒等。
3.进行数据分析:将数据导入内存,进行统计报表分析。
Redis的String探索之路的更多相关文章
- 二、Redis基本操作——String(实战篇)
小喵万万没想到,上一篇博客,居然已经被阅读600次了!!!让小喵感觉压力颇大.万一有写错的地方,岂不是会误导很多筒子们.所以,恳请大家,如果看到小喵的博客有什么不对的地方,请尽快指正!谢谢! 小喵的唠 ...
- 一、Redis基本操作——String(原理篇)
小喵的唠叨话:最近京东图书大减价,小喵手痒了就买了本<Redis设计与实现>[1]来看看.这里权当小喵看书的笔记啦.这一系列的模式,主要是先介绍Redis的实现原理(可能很大一部分会直接照 ...
- Redis之String
一.Redis之String简介 1. String是redis最基本的数据类型,一个key对应一个value. 2. String是二进制安全的,可以包含任何数据,例如图片或序列化的对象. 3. S ...
- redis对string进行的相关操作
redis对string类型操作的相关命令以及如何在python使用这些命令 redis对string类型操作的命令: 命令 语法 概述 返回值 Redis SET 命令 set key value ...
- Redis操作string
Redis简介: ''' redis: 缓存,例如两个个程序A,B之间要进行数据共享,A可以把数据存在redis(内存里),其他程序都可以访问redis里的数据, 这样通过中间商redis就实现了两个 ...
- Redis学习-string数据类型
Redis 是一个开源的使用 ANSI C 语言编写.支持网络.可基于内存亦可持久化的日志 型.Key-Value 数据库. redis提供五种数据类型string,hash,list,set及sor ...
- 使用Redis数据库(String类型)
一 String类型 首先使用启动服务器进程 : redis-server.exe 1. Set 设置Key对应的值为String 类型的value. 例子:向 Redis数据库中插入一条数据类型为S ...
- PHP操作redis之String(字符串)、List(列表)(一)
Redis 简介 Redis 是完全开源免费的,遵守BSD协议,是一个高性能的key-value数据库. Redis 与其他 key – value 缓存产品有以下三个特点: Redis支持数据的持久 ...
- Redis的String、Hash类型命令
String是最简单的类型,一个Key对应一个Value,string类型是二进制安全的.Redis的string可以包含任何数据,比如jpg图片或者序列化的对象.最大上限是1G字节. Hash ...
随机推荐
- 前端基础进阶(十一):详细图解jQuery对象,以及如何扩展jQuery插件
早几年学习前端,大家都非常热衷于研究jQuery源码.我还记得当初从jQuery源码中学到一星半点应用技巧的时候常会有一种发自内心的惊叹,“原来JavaScript居然可以这样用!” 虽然随着前端的发 ...
- [Objective-C] 006_Protocol(协议)
学过java的同学都知道Interface(接口),那么在Objective-C中有没有接口呢?其实 Objective-C中用Protocol(协议)来实现的,在Objective-C具体怎么用,我 ...
- [安卓基础] 007.管理Activity的生命周期
*:first-child { margin-top: 0 !important; } body > *:last-child { margin-bottom: 0 !important; } ...
- 节点流(文件流) FileInputStream & FileOutputStream & FileReader & FileWriter
节点流(文件流) FileInputStream(字节流)处理视频类的 FileOutputStream(字节流) FileReader(字符流)处理文本文件 ...
- 派生类Student的构造函数和析构函数 代码参考
#include <iostream> #include <cstring> using namespace std; class Person { private: char ...
- Java rmi漏洞利用及原理记录
CVE-2011-3556 该模块利用了RMI的默认配置.注册表和RMI激活服务,允许加载类来自任何远程(HTTP)URL.当它在RMI中调用一个方法时分布式垃圾收集器,可通过每个RMI使用endpo ...
- 关于thisState的那些事
1.state的定义 状态(state) 和 属性(props) 类似,都是一个组件所需要的一些数据集合,但是它是私有的,并且由组件本身完全控制,可以认为它是组件的“私有属性(或者是局部属性)”. 2 ...
- Java 第十一届 蓝桥杯 省模拟赛 反倍数
反倍数 题目 问题描述 给定三个整数 a, b, c,如果一个整数既不是 a 的整数倍也不是 b 的整数倍还不是 c 的整数倍,则这个数称为反倍数. 请问在 1 至 n 中有多少个反倍数. 输入格式 ...
- Java实现 蓝桥杯VIP 算法提高 产生数
算法提高 产生数 时间限制:1.0s 内存限制:256.0MB 问题描述 给出一个整数 n(n<10^30) 和 k 个变换规则(k<=15). 规则: 一位数可变换成另一个一位数: 规则 ...
- Java实现8枚硬币问题(减治法)
1 问题描述 在8枚外观相同的硬币中,有一枚是假币,并且已知假币与真币的重量不同,但不知道假币与真币相比较轻还是较重.可以通过一架天平来任意比较两组硬币,设计一个高效的算法来检测这枚假币. 2.1 减 ...