NoSQL,从Redis开始(一)
- 数据库
- 2023-01-23
前言:
做开发几年了,期间也接触过几种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
6) 连接redis
redis-cli
2.apt-get安装
1) apt-get命令直接安装
apt-get installredis-server
2) dpkg-query查看redis安装的相关文件
dpkg-query -Lredis-server
3) 查看redis版本
redis-cli--version
4) 重启redis
systemctl restartredis
5) 设置开机自动启动redis
systemctl enableredis
6) 打开远程访问
vim/etc/redis/redis.conf
7) 连接redis
redis-cli
3.编译安装
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函数为获取该字符串的值。
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种设计模式中的观察者模式极为相似。
同样,Redis的pub/sub是一种消息通信模式,主要的目的是解除消息发布者和消息订阅者之间的耦合,Redis作为一个pub/sub的server,在订阅者和发布者之间起到了消息路由的功能,它们之间的关系如上图。1、SUBSCRIBE命令:
该命令的作用,就是让客户端去订阅一个或多个它想要订阅的频道。例如:如下图所示,客户端client1、client2、client3分别订阅了tiopsChannel和tisecChannel频道。
上图中,client1、client2都订阅了tiopsChannel,而client2、client3则都订阅了tisecChannel。
这就是SUBSCRIBE命令的作用,在客户端执行以下语法:
subscribe 频道1 [频道2] [频道3] [频道4] ......
2、PUBLISH命令:
该命令的作用,就是从频道服务端发送一条或多条信息到订阅该频道的客户端处。根据上图做变形,就变成下图所示:
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
AWS EC2的价格模型