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 capacity; // 数组容量 T len; // 数组长度 byte flags; // 特殊标识位,不理睬它 byte[] content; // 数组内容 }
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 字节的存储空间。
struct SDS { int8 capacity; // 1byte int8 len; // 1byte int8 flags; // 1byte byte[] content; // 内联数组,长度为 capacity(默认开辟的空间) }
content+3
content
中的字符串是以字节\0
结尾的字符串,之所以多出这样一个字节,是为了便于直接使用 glibc
- 当内存分配器分配了 64 空间时,那这个字符串的长度(内容)最大可以是多少呢?
64 - 19 - 1 = 44(字节)
127.0.0.1:6379> set content aaaabbbbccccddddeeeeffffgggghhhhiiiijjjjkkkk OK 127.0.0.1:6379> debug object content Value at:0x7f4f4f0c3a40 refcount:1 encoding:embstr serializedlength:45 lru:15180126 lru_seconds_idle:13 127.0.0.1:6379> append content l (integer) 45 127.0.0.1:6379> debug object content Value at:0x7f4f4f0adc20 refcount:1 encoding:raw serializedlength:46 lru:15180178 lru_seconds_idle:19
(1)可以用来计数
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 "9223372036854775807" 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.进行数据分析:将数据导入内存,进行统计报表分析。