Redis 简单认识和String字符串类型

Redis中16个默认数据库

Redis默认支持16个数据库,可以通过调整Redis的配置文件redis/redis.conf中的databases来修改这一个值,设置完毕后重启Redis便完成配置。

客户端与Redis建立连接后会默认选择0号数据库,不过可以随时使用SELECT命令更换数据库。

# 切库redis> SELECT 1 # 默认0号db,切换为2

Redis 简单认识和String字符串类型

由于Redis不支持自定义数据库的名字,所以每个数据库都以编号命名。开发者则需要自己记录存储的数据与数据库的对应关系。另外Redis也不支持为每个数据库设置不同的访问密码,所以一个客户端要么可以访问全部数据库,要么全部数据库都没有权限访问。但是,要正确地理解Redis的“数据库”概念这里不得不提到一个命令:

# 清空一个Redis实例中所有数据库中的数据redis 127.0.0.1:6379> FLUSHALL

该命令可以清空实例下的所有数据库数据,这与我们所熟知的关系型数据库所不同。关系型数据库多个库常用于存储不同应用程序的数据 ,且没有方式可以同时清空实例下的所有库数据。所以对于Redis来说这些db更像是一种命名空间,且不适宜存储不同应用程序的数据。比如可以使用0号数据库存储某个应用生产环境中的数据,使用1号数据库存储测试环境中的数据,但不适宜使用0号数据库存储A应用的数据而使用1号数据库B应用的数据,不同的应用应该使用不同的Redis实例存储数据。Redis非常轻量级,一个空Redis实例占用的内在只有1M左右,所以不用担心多个Redis实例会额外占用很多内存。最后要注意,Redis集群下只有db0,不支持多db。

2 redis中对象的类型与编码

每当我们在redis的数据库中新建立一个键值对时,redis会至少创建两个对象,一个对象用作键,一个对象用作值,其中键的对象一定是字符串对象,值的对象是字符串,列表,哈希,集合,有序集合中的一种

redis中每个对象都由一个redisObject的结构表示

Redis 简单认识和String字符串类型

type属性记录了对象的类型,这个属性的值对应如下表

Redis 简单认识和String字符串类型

当我们对一个数据库键执行TYPE命令时,会返回数据库键对应的值对象的类型

Redis 简单认识和String字符串类型

type属性和encoding属性的对应关系

Redis 简单认识和String字符串类型

3 String 类型

3.1 字符串类型,简单命令使用,通过help @string,查看使用命令

Redis 简单认识和String字符串类型

set

 可以通过help set查看如何使用

Redis 简单认识和String字符串类型

seconds – 设置过期时间,单位为秒.

PX milliseconds – 设置过期时间,单位为毫秒.

NX – key值不存在的时候,才创建.

XX – key值已存在的时候,才更新.

Get

获取key中设置的字符串值

语法: get key

Redis 简单认识和String字符串类型

Set k1 world NX

Redis 简单认识和String字符串类型

Set k1 world   XX

Redis 简单认识和String字符串类型

Strlen

Redis 简单认识和String字符串类型

Append

Setrange

Getrange

Mset

mget

这里不一一列举了。

3.2 二进制安全

C字符串中的字符必须符合某种编码(比如ASCII),并且除了字符串的末尾之外,字符串里面不能包含空字符,否则最先被程序读入的空字符将被误认为是字符串结尾,这些限制使得C字符串只能保存文本数据,而不能保存像图片、音频、视频、压缩文件这样的二进制数据

举个例子,如果有一种使用空字符来分割多个单词的特殊数据格式,如图所示,那么这种格式就不能使用C字符串来保存,因为C字符串所用的函数只会识别出其中的"Redis",而忽略之后的"Cluster"

Redis 简单认识和String字符串类型

因此,为了确保Redis可以适用于各种不同的使用场景,SDS(simple dynamid string )的 API都是二进制安全的(binary-safe),所有SDS API都会以处理二进制的方式来处理SDS存放在buf数组里的数据程序不会对其中的数据做任何限制、过滤、或者假设,数据在写入时是什么样的,它被读 取时就是什么样。

  这也是我们将SDS的buf属性称为字节数组的原因——Redis不是用这个数组来保存字符,而是用它来保存一系列二进制数据。例如,使用SDS来保存之前提到的特殊数据格式就没有任何问题,因为SDS使用len属性的值而不是空字符来判断字符串是否结束

Redis 简单认识和String字符串类型

通过使用二进制安全的SDS,而不是C字符串,使得Redis不仅可以保存文本数据,还可以保存任意格式的二进制数据。

struct sdshdr {

int len;//记录buf数组大小

int free;//记录buf数组还有多少可用空间

char buf[];//字符串实体,保存字符串的内容

};

因为有了对字符串长度定义len, 所以在处理字符串时候不会以零值字节(\0)为字符串结尾标志.

二进制安全就是输入任何字节都能正确处理, 即使包含零值字节.

3.2 数值

Incr

将 key 中储存的数字值加 1,如果 key 不存在,则 key 的 值先被初始化为 0 再执行

incr 操作(只能对数字类型的数据操作)

语法:incr key

Redis 简单认识和String字符串类型

decr

将 key 中储存的数字值减1,

如果 key 不存在,则么 key 的值先被 初始化为 0 再执 行

decr 操作(只能对数字类型的数据操作)

语法:decr key

Redis 简单认识和String字符串类型

INCRBY kk 10

DECRBY kk 10

Redis 简单认识和String字符串类型

3.3 incr的使用场景

抢购,秒杀,规避高并发下对数据库的事务操作

需求:是需要限制一个号码一分钟内只能获取一次验证码,之前的实现是短信发送请求过来后,先去数据库查询发送记录,根据上一次的短信发送时间和当前时间比较,如果时间差小于一分钟,则提示短信获取频繁,如果超过一分钟,则发送短信,并记录短信发送日志。

这样的操作其实是有问题的。当同一时间有很多请求过来时,同时去查库,同时获取到上一次发送时间,有可能就会重复发送短信了。

incr 可以实现原子性的递增,可应用于高并发的秒杀活动、分布式***生成等场景。这里我使用它来计数实现一分钟内只接受一次请求。

我们在后台接到短信发送请求后,使用Redis的incr设置一个递增KEY(KEY由固定字符串+手机号码组成),并判断该KEY的数值,如果等于1,说明是第一个请求,我们将该KEY值有效期设置为一分钟;如果该KEY的数值大于1,说明是1分钟内的多次请求,这时我们直接返回短信获取频繁

3.4 bitmap 基本命令使用

BitMap,即位图,其实也就是 byte 数组,用二进制表示,只有 0 和 1 两个数字。

Redis 简单认识和String字符串类型

offset:是二进制位的偏移量,而不是字节数组。一个字节有8个二进制位

Start: 是指第几个字节,而不是二进制位

End:    是指第几个字节,而不是二进制位

Redis 简单认识和String字符串类型

Redis 简单认识和String字符串类型

将k1的第一个(索引为0)二进制位设置为1:

Redis 简单认识和String字符串类型

在ASCII码表中,01000000刚好就是@:

将k1的第八个(索引为7)二进制位设置为1:01000001对应的就是A

Redis 简单认识和String字符串类型

使用man ascii来验证:

如果没有安装man,需要安装一下:

yum install man man-pages

Redis 简单认识和String字符串类型

将第十个二进制位(索引为9)的值设置为1:得到的结果将是[email protected],就是将两个字节按照ASCII表分别转换为字符后拼接起来

Redis 简单认识和String字符串类型

setbit k2 1 1

setbit k2 6 1

得到'B'

Redis 简单认识和String字符串类型

将k1和k2进行与运算:与运算,遇0则0,全为1则为1

Redis 简单认识和String字符串类型

将k1和k2进行或运算:或运算,遇1则1,全为0则为0

Redis 简单认识和String字符串类型

应用场景

bitmap的应用场景一:

统计用户的登录天数,且窗口随机。

460M能存储1000万用户全年365天的登录明细:365/8=46B(字节)

Redis 简单认识和String字符串类型

(01,02,03,04为日期;sean,json为用户id)

比如:用户sean第2天登录过,第8天,第365天登录过

Redis 简单认识和String字符串类型

统计一个用户一年内的登录天数顶多需要46字节:

Redis 简单认识和String字符串类型

计算用户sean最后两周的登录天数:(最后一周是-1,倒数第二周是-2),结果是1次

bitcount 统计的是1的个数  bitcount test 0 -1 就是所有的  bitcount 0 0 那么就应该是第一个字节中1的数量的

Redis 简单认识和String字符串类型

Redis 简单认识和String字符串类型

 

应用场景二:

统计活跃用户数:以登录日期为key;重复登录要去重;进行or或运算(有1则1);

Redis 简单认识和String字符串类型

Redis 简单认识和String字符串类型