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. 【C++】VS Code配置

    0.前言 本文已配置C++环境为例,本文主要是面向刚开始接触VS Code的朋友,采用生成默认配置任务的方法,在编写本文过程中大量参考了官方文档,感兴趣的朋友可直接前往传送门. 环境: win10 + ...

  2. java类的方法的使用

    类的方法:提供某种功能的实现: 实例:public void eat (){ } public String  getName(){ } public void  setName(String n){ ...

  3. Rocket - diplomacy - ValName

    https://mp.weixin.qq.com/s/so-2x5KLfYF0IMCCqNThwQ   简单调试ValName实现:   1. 使用     ​​   Desugar之后如下: ​​ ...

  4. Chisel3 - model - when

    https://mp.weixin.qq.com/s/YGTXky4wff7LXUphUxISQg   介绍创建模块判断逻辑的when命令.   1. when/elsewhen/otherwise ...

  5. Java实现 蓝桥杯VIP 算法提高 研究兔子的土豪

    试题 算法提高 研究兔子的土豪 资源限制 时间限制:1.0s 内存限制:256.0MB 问题描述 某天,HWD老师开始研究兔子,因为他是个土豪 ,所以他居然一下子买了一个可以容纳10^18代兔子的巨大 ...

  6. Java实现桐桐的数学难题

    桐桐的数学难题 题目描述 今天数学课上,桐桐学习了质数的知识:一个正整数如果只能被1和它本身整除,那么这个整数便是质数.桐桐就想:任意一个正整数是否都能分解成若干个质数相乘的形式呢?输入一个正整数n( ...

  7. Java实现 LeetCode 129 求根到叶子节点数字之和

    129. 求根到叶子节点数字之和 给定一个二叉树,它的每个结点都存放一个 0-9 的数字,每条从根到叶子节点的路径都代表一个数字. 例如,从根到叶子节点路径 1->2->3 代表数字 12 ...

  8. Java实现 蓝桥杯 乘积最大

    输入输出样例 输入样例#1: 4 2 1231 输出样例#1: 62 import java.util.Scanner; public class chengjizuida { public stat ...

  9. ZSH隐藏命令行前面的用户名和主机名

    修改vim ~/.zshrc文件,在文件底部增加 隐藏用户名和主机名 prompt_context() {} 只保留用户名,隐藏主机名 prompt_context() { if [[ "$ ...

  10. HDFS ha 格式化报错:a shared edits dir must not be specified if HA is not enabled.

    错误内容: Formatting using clusterid: CID-19921335-620f-4e72-a056-899702613a6b2019-01-12 07:28:46,986 IN ...