NoSQL,从Redis开始(一)

前言:

做开发几年了,期间也接触过几种NoSql数据库,比如redis、mongodb、memcache等。但是一直没有很好的、系统的和全面的梳理过它们的知识点。

今天,我就从Redis开始,先做一个关于redis的系列文章。主要包括以下部分:

1.Redis的安装、基本数据结构、python客户端、pub/sub命令

2.数据结构的实现、内存管理、php客户端、高级特性Geo

3.RDB持久化、AOF持久化、Java客户端、高级特性HyperLogLog

4.哨兵、集群以及结合devops

5.……

本篇文章就先从第1个开始。

1

Redis的安装

本文主要讲解redis在liunx上的安装,windows上的redis安装暂时不在本文的讨论范围。

1.yum安装

1) yum命令直接安装

yum install -y redis

2) 查看redis版本

redis-cli –version

3) 重启redis

systemctl restart redis

4) 设置开机自动启动redis

systemctl enable redis

5) 打开远程访问

vim /etc/redis.conf

NoSQL,从Redis开始(一)

6) 连接redis

redis-cli

2.apt-get安装

1) apt-get命令直接安装

apt-get installredis-server

2) dpkg-query查看redis安装的相关文件

dpkg-query -Lredis-server

NoSQL,从Redis开始(一)

3) 查看redis版本

redis-cli–version

4) 重启redis

systemctl restartredis

5) 设置开机自动启动redis

systemctl enableredis

6) 打开远程访问

vim/etc/redis/redis.conf

NoSQL,从Redis开始(一)

7) 连接redis

redis-cli

3.编译安装

NoSQL,从Redis开始(一)

2

基本数据结构

1、字符串类型:是Redis最简单的数据结构,与python中的字符串类似。

命令

作用

备注

GET 获取指定key的值 GET key
SET 设置指定key的值 SET key value value如果有空格需要加引号
MGET 获取多个键值 MGET key [key …]
MSET 设置多个键值 MSET key value [key value …]
INCR 整数递增 INCR key
INCRBY 增加指定的整数 INCRBY key increment
INCRBYFLOAT 增加指定的浮点数 INCRBYFLOAT key increment
DECR 整数递减 DECR key
DECRBY 减少指定的整数 DECRBY key increment
APPEND 向尾部追加值 APPEND key value
STRLEN 获取字符串长度 STRLEN key
GETBIT 获取二进制位置值 GETBIT key offset
SETBIT 设置二进制位置值 SETBIT key offset value
BITCOUNT 二进制是1的个数 BITCOUNT key [start end]
BITOP 位运算 BITOP operation destkey key [key …],operation支持AND、OR、XOR、NOT
BITPOS 偏移 BITPOS key bit [start] [end]

2、hash类型:类似于python中的dict,一个key对应一个value。注意,redis中hash的值只能是字符串。

命令

作用

备注

HSET 设置单个 HSET key field value,不存在时返回1,存在时返回0
HGET 读取单个 HGET key field,不存在是返回nil
HMSET 设置多个 HMSET key field value [field value …]
HMGET 读取多个 HMGET key field [field …]
HGETALL 读取全部 HGETALL key,返回时字段和字段值的列表
HEXISTS 判断字段是否存在 HEXISTS key field,存在返回1,不存在返回0
HSETNX 字段不存在时赋值 HSETNX key field value,与hset命令不同,hsetnx是键不存在时设置值
HINCRBY 增加数字 HINCRBY key field increment,返回增加后的数,不是整数时会提示错误
HDEL 删除字段 HDEL key field [field …] ,返回被删除字段的个数
HKEYS 只获取字段名 HKEYS key,返回键的所有字段名
HVALS 只获取字段值 HVALS key,返回键的所有字段值
HLEN 字段数量 HLEN key,返回字段总数

3、列表类型:类似于python中的list,用pop和push的方式输入和输出元素,是消息队列的首要选择。

命令

作用

备注

LPUSH 添加左边元素 LPUSH key value [value …]
LPOP 移除左边第一个元素 LPOP key
RPUSH 添加右边元素 RPUSH key value [value …]
RPOP 移除右边第一个元素 RPOP key
LLEN 列表元素个数 LLEN key
LRANGE 获取列表片段 LRANGE key start stop
LREM 删除指定值 LREM key count value
LINDEX 索引元素值 LINDEX key index
LSET 设置元素值 LSET key index value
LTRIM 保留列表片段 LTRIM key start stop,start、top
RPOPLPUSH 列表转移 RPOPLPUSH source desctination,从source列表转移到desctination列表

4、集合类型:类似于python中的set,内部的键值是无序且唯一的。

命令

作用

备注

SADD 添加元素 SADD key member [member …]
SREM 删除元素 SREM key member [member …]
SMEMBERS 获取全部元素 SMEMBERS key
SISMEMBER 判断值是否存在 SISMEMBER key member
SDIFF 差运算 SDIFF key [key …]
SINTER 交运算 SINTER key [key …]
SUNION     并运算 SUNION key [key …]
SCARD 集合元素个数 SCARD key
SDIFFSTROE 差运算并存储到新集合中 SDIFFSTROE destination key [key …]
SINTERSTROE 交运算并存储到新集合中 SINTERSTROE destination key [key …]
SUNIONSTROE 并运算并存储到新集合中 SUNIONSTROE destination key [key …]
SRANDMEMGER 随机获取元素 SRANDMEMBER key [count]
SPOP 弹出元素 SPOP key [count]

5、有序集合类型:是redis中最有特色的数据结构,一方面它是一个set,另一方面它可以给每个value赋予一个score,代表这个value的排序权重。

命令

作用

备注

ZADD 添加集合元素 ZADD key [NX|XX] [CH] [INCR] score member [score member …]
ZSCORE 获取元素分数 ZSCORE key member
ZRANGE 元素小到大 ZRANGE key start top [WITHSCORES]
ZREVRANGE 元素大到小 ZREVRANGE key start [WITHSCORES]
ZRANGEBYSCORE 指定分数范围元素,从小到大 ZRANGEBYSCORE key min max [WITHSCORE] [LIMIT offest count]
ZREVRANGESCORE 指定分数范围元素,从大到小 ZREVRANGEBYSCORE key max min [WITHSCORE] [LIMIT offest count]
ZINCRBY 增加分数 ZINCRBY key increment member

3

python客户端

Python操控redis,需要安装python的redis模块。很简单,使用pip的方式安装:pip install redis。

1、python连接redis的方式,分两种:

1)直接连接

r = redis.Redis(host=’localhost’, port=6379,decode_responses=True)

2)连接池连接

pool = redis.ConnectionPool(host=’localhost’,port=6379, decode_responses=True)

r = redis.Redis(connection_pool=pool)

2、使用举例

如下图所示,下图代码就是python调用redis的一个简单示例。其中set函数为创建一个key为name,value为tiops的字符串类型,若存在则修改。get函数为获取该字符串的值。

NoSQL,从Redis开始(一)

Redis的函数就不一一讲解了,下面有其总结。

1)公共操作

函数

备注

delete(*names) 删除
expire(name ,time) 设置超时时间
exists(name) 检查名字是否存在
keys(pattern=”) 模糊匹配
rename(src, dst) 重命名
type(name) 获取类型
randomkey() 随机获取name
scan(cursor=0, match=None, count=None) 查看所有元素
scan_iter(match=None, count=None) 查看所有元素–迭代器

2)字符串类型

函数

备注

set(name, value, ex=None, px=None, nx=False, xx=False) 设置值,在就创建,不在修改。

ex,过期时间(秒)

px,过期时间(毫秒)

nx,如果设置为True,则只有name不存在时,当前set操作才执行

xx,如果设置为True,则只有name存在时,当前set操作才执行

setnx(name, value) 设置值,只有name不存在时,执行设置操作
setex(name, value, time) 设置值,并设置过期时间,time单位秒
psetex(name, time_ms, value) 设置值,并设置过期时间,time_ms单位毫秒
mset(args, *kwargs) 批量设置值
mget(keys, *args) 批量获取值
getset(name, value) 设置新值并获取原来的值
getrange(key, start, end) 获取指定范围内的值
setrange(name, offset, value) 修改指定范围内的值
setbit(name, offset, value) 对name对应值的二进制进行位操作
getbit(name, offset) 获取name对应的值的二进制表示中的某位的值 (0或1)
bitcount(key, start=None, end=None) 获取name对应的值的二进制表示中1的个数
bitop(operation, dest, *keys) 获取多个值,并将值做位运算,将最后的结果保存至新的name对应的值
strlen(name) 返回name对应值的字节长度(一个汉字3个字节)
incr(self, name, amount=1) 自增name对应的值(增加整数)
incrbyfloat(self, name, amount=1.0) 自增name对应的值(增加浮点数)
decr(self, name, amount=1) 自减name对应的值(减少整数)
append(key, value) 值后面追加内容

3)Hash类型

函数

备注

hset(name, key, value) 对应的key设置一个value
hsetnx(name, key, value) 对应的key设置一个value,不存在才执行
hmset(name, mapping) 批量增加
hget(name,key) 根据key获取value
hmget(name, keys, *args) 获取多个key的值
hgetall(name) 取出所有的键值对
hlen(name) 获取键值对的个数
hkeys(name) 获取所有的key的值
hvals(name) 获取所有的value的值
hexists(name, key) 检查是否存在当前传入的key
hdel(name,*keys) 将指定key的键值对删除
hincrby(name, key, amount=1) 自增指定key的值,整数
hincrbyfloat(name, key, amount=1.0) 自增指定key的值,浮点数
hscan(name, cursor=0, match=None, count=None) 增量式迭代获取,对于数据大的数据非常有用,hscan可以实现分片的获取数据,并非一次性将数据全部获取完
hscan_iter(name, match=None, count=None) 利用yield封装hscan创建生成器,实现分批去redis中获取数据

4) 列表类型

函数

备注

lpush(name,values) 从左边增加,没有的话就创建
lpushx(name,value) 从左边增加,没有的话无法创建
rpush(name,values) 从右边增加,没有的话就创建
rpushx(name,value) 从右边增加,没有的话无法创建
linsert(name, where, refvalue, value)) 在name对应的列表的某一个值前或后插入一个新值
lset(name, index, value) 指定索引号进行修改
lrem(name, value, num) 指定值进行删除
lpop(name) 删除并返回
ltrim(name, start, end) 删除索引之外的值
lindex(name, index) 根据索引取值
rpoplpush(src, dst) 元素从一个列表移动到另一个列表
brpoplpush(src, dst, timeout=0) 元素从一个列表移动到另一个列表,设置超时
blpop(keys, timeout) 一次移除多个列表

5) 集合类型

函数

备注

sadd(name,values) 新增
scard(name) 获取元素个数
smembers(name) 获取集合中所有的成员
sdiff(keys, *args) 差集
sdiffstore(dest, keys, *args) 差集并存到一个新的集合中
sinter(keys, *args) 交集
sinterstore(dest, keys, *args) 交集并存到一个新的集合中
sunion(keys, *args) 并集
sunionstore(dest,keys, *args) 并集并存到一个新的集合
sismember(name, value) 判断是否是集合的成员
smove(src, dst, value) 移动
spop(name) 随机删除并且返回被删除值
srem(name, values) 指定值删除

6) 有序集合类型

函数

备注

zadd(name, args, *kwargs) 新增
zcard(name) 获取有序集合元素个数
zrange( name, start, end,desc=False, withscores=False, score_cast_func=float) 按照索引范围获取name对应的有序集合的元素
zrevrange(name, start, end, withscores=False, score_cast_func=float) 按照索引范围获取name对应的有序集合的元素,从大到小排序
zrangebyscore(name, min, max,start=None, num=None, withscores=False, score_cast_func=float) 按照分数范围获取name对应的有序集合的元素
zrevrangebyscore(name, max, min,start=None, num=None, withscores=False, score_cast_func=float) 按照分数范围获取name对应的有序集合的元素,从大到小排序
zscan(name,cursor=0, match=None, count=None, score_cast_func=float) 获取所有元素
zscan_iter(name,match=None, count=None,score_cast_func=float) 获取所有元素–迭代器
zcount(name, min, max) 获取name对应的有序集合中分数在min,max之间的个数
zincrby(name, value, amount) 自增
zrank(name, value) 获取值的索引号
zrevrank(name, value) 获取值的索引号,从大到小排序
zrem(name, values) 指定值删除
zremrangebyrank(name, min, max) 根据索引号删除
zremrangebyscore(name, min, max) 根据分数范围删除
zscore(name, value) 获取值对应的分数

4

Redis中的pub/sub

我们生活中的订阅功能就是由pub/sub功能实现的,最简单的例子:您订阅了我们新钛云服的公众号,等我们新钛云服公众号发送新文章时,就会第一时间通知您。

道理相同,redis中pub/sub也是一种实现Pub/Sub功能的方式。了解redis的pub/sub之前,我们要先清楚Pub/Sub功能的定义:

Pub/Sub功能(meansPublish, Subscribe)即发布及订阅功能。基于事件的系统中,Pub/Sub是目前广泛使用的通信模型,它采用事件作为基本的通信机制,提供大规模系统所要求的松散耦合的交互模式:订阅者(如客户端)以事件订阅的方式,表达出它有兴趣接收的一个事件或一类事件;发布者(如服务器)可将订阅者感兴趣的事件随时通知相关订阅者。熟悉设计模式的朋友应该了解这与23种设计模式中的观察者模式极为相似。

NoSQL,从Redis开始(一)

同样,Redis的pub/sub是一种消息通信模式,主要的目的是解除消息发布者和消息订阅者之间的耦合,Redis作为一个pub/sub的server,在订阅者和发布者之间起到了消息路由的功能,它们之间的关系如上图。

1、SUBSCRIBE命令

该命令的作用,就是让客户端去订阅一个或多个它想要订阅的频道。例如:如下图所示,客户端client1、client2、client3分别订阅了tiopsChannel和tisecChannel频道。

NoSQL,从Redis开始(一)

上图中,client1、client2都订阅了tiopsChannel,而client2、client3则都订阅了tisecChannel。

这就是SUBSCRIBE命令的作用,在客户端执行以下语法:

subscribe 频道1 [频道2] [频道3] [频道4] ……

2、PUBLISH命令:

该命令的作用,就是从频道服务端发送一条或多条信息到订阅该频道的客户端处。根据上图做变形,就变成下图所示:

NoSQL,从Redis开始(一)

PUBLISH命令语法:

publish 频道1 “信息”

3、命令总结:

命令

作用

备注

SUBSCRIBE 订阅频道 SUBSCRIBE channel [channel …]
UNSUBSCRIBE 退订频道 UNSUBSCRIBE channel [channel …]
PSUBSCRIBE 正则的方式订阅频道 PSUBSCRIBE pattern [pattern …]
PUNSUBSCRIBE 正则的方式退订频道 PUNSUBSCRIBE [pattern [pattern …]]
PUBLISH 频道推送信息 PUBLISH channel “message”
PUBSUB 查看订阅与发布系统状态 PUBSUB <subcommand> [argument [argument …]]