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 value
  • NX :在键不存在时, 才对键进行设置操作。
  • 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探索之路的更多相关文章

  1. 二、Redis基本操作——String(实战篇)

    小喵万万没想到,上一篇博客,居然已经被阅读600次了!!!让小喵感觉压力颇大.万一有写错的地方,岂不是会误导很多筒子们.所以,恳请大家,如果看到小喵的博客有什么不对的地方,请尽快指正!谢谢! 小喵的唠 ...

  2. 一、Redis基本操作——String(原理篇)

    小喵的唠叨话:最近京东图书大减价,小喵手痒了就买了本<Redis设计与实现>[1]来看看.这里权当小喵看书的笔记啦.这一系列的模式,主要是先介绍Redis的实现原理(可能很大一部分会直接照 ...

  3. Redis之String

    一.Redis之String简介 1. String是redis最基本的数据类型,一个key对应一个value. 2. String是二进制安全的,可以包含任何数据,例如图片或序列化的对象. 3. S ...

  4. redis对string进行的相关操作

    redis对string类型操作的相关命令以及如何在python使用这些命令 redis对string类型操作的命令: 命令 语法 概述 返回值 Redis SET 命令  set key value ...

  5. Redis操作string

    Redis简介: ''' redis: 缓存,例如两个个程序A,B之间要进行数据共享,A可以把数据存在redis(内存里),其他程序都可以访问redis里的数据, 这样通过中间商redis就实现了两个 ...

  6. Redis学习-string数据类型

    Redis 是一个开源的使用 ANSI C 语言编写.支持网络.可基于内存亦可持久化的日志 型.Key-Value 数据库. redis提供五种数据类型string,hash,list,set及sor ...

  7. 使用Redis数据库(String类型)

    一 String类型 首先使用启动服务器进程 : redis-server.exe 1. Set 设置Key对应的值为String 类型的value. 例子:向 Redis数据库中插入一条数据类型为S ...

  8. PHP操作redis之String(字符串)、List(列表)(一)

    Redis 简介 Redis 是完全开源免费的,遵守BSD协议,是一个高性能的key-value数据库. Redis 与其他 key – value 缓存产品有以下三个特点: Redis支持数据的持久 ...

  9. Redis的String、Hash类型命令

    String是最简单的类型,一个Key对应一个Value,string类型是二进制安全的.Redis的string可以包含任何数据,比如jpg图片或者序列化的对象.最大上限是1G字节.    Hash ...

随机推荐

  1. 前端基础进阶(十一):详细图解jQuery对象,以及如何扩展jQuery插件

    早几年学习前端,大家都非常热衷于研究jQuery源码.我还记得当初从jQuery源码中学到一星半点应用技巧的时候常会有一种发自内心的惊叹,“原来JavaScript居然可以这样用!” 虽然随着前端的发 ...

  2. [Objective-C] 006_Protocol(协议)

    学过java的同学都知道Interface(接口),那么在Objective-C中有没有接口呢?其实 Objective-C中用Protocol(协议)来实现的,在Objective-C具体怎么用,我 ...

  3. [安卓基础] 007.管理Activity的生命周期

    *:first-child { margin-top: 0 !important; } body > *:last-child { margin-bottom: 0 !important; } ...

  4. 节点流(文件流) FileInputStream & FileOutputStream & FileReader & FileWriter

    节点流(文件流) FileInputStream(字节流)处理视频类的                   FileOutputStream(字节流) FileReader(字符流)处理文本文件    ...

  5. 派生类Student的构造函数和析构函数 代码参考

    #include <iostream> #include <cstring> using namespace std; class Person { private: char ...

  6. Java rmi漏洞利用及原理记录

    CVE-2011-3556 该模块利用了RMI的默认配置.注册表和RMI激活服务,允许加载类来自任何远程(HTTP)URL.当它在RMI中调用一个方法时分布式垃圾收集器,可通过每个RMI使用endpo ...

  7. 关于thisState的那些事

    1.state的定义 状态(state) 和 属性(props) 类似,都是一个组件所需要的一些数据集合,但是它是私有的,并且由组件本身完全控制,可以认为它是组件的“私有属性(或者是局部属性)”. 2 ...

  8. Java 第十一届 蓝桥杯 省模拟赛 反倍数

    反倍数 题目 问题描述 给定三个整数 a, b, c,如果一个整数既不是 a 的整数倍也不是 b 的整数倍还不是 c 的整数倍,则这个数称为反倍数. 请问在 1 至 n 中有多少个反倍数. 输入格式 ...

  9. Java实现 蓝桥杯VIP 算法提高 产生数

    算法提高 产生数 时间限制:1.0s 内存限制:256.0MB 问题描述 给出一个整数 n(n<10^30) 和 k 个变换规则(k<=15). 规则: 一位数可变换成另一个一位数: 规则 ...

  10. Java实现8枚硬币问题(减治法)

    1 问题描述 在8枚外观相同的硬币中,有一枚是假币,并且已知假币与真币的重量不同,但不知道假币与真币相比较轻还是较重.可以通过一架天平来任意比较两组硬币,设计一个高效的算法来检测这枚假币. 2.1 减 ...