10.Redis编程入门

本主题主要是Redis的基本入门,包含内容:
  1. Redis的安装与配置
  2.Redis的命令行操作
  3.Redis Python编程操作编程

一、下载与安装

1. 下载

1.1. 下载地址:

  | - https://redis.io/download

10.Redis编程入门_第1张图片
Redis下载

1.2. 下载的是tar压缩文件

  redis-5.0.3.tar
  下面是下载的截图

10.Redis编程入门_第2张图片
redis-5.0.3.tar,如果需要集群版本,应该下载stable版本

2. 安装

2.1. 解压缩指令

使用tar压缩工具解压缩:
  tar -xf redis-5.0.3.tar

yangqiangdeMacBook-Pro:Downloads yangqiang$ tar -xf redis-5.0.3.tar
Redis解压缩目录

编译

进入解压缩目录,使用make执行编译:


10.Redis编程入门_第3张图片
Redis编译

2.2. 安装

执行make install实现安装


10.Redis编程入门_第4张图片
Redis安装

二、配置

1. 配置服务目录与文件

1.1. 配置目录

在/usr/local/目录下(也可以在其他目录下)创建redis服务器目录,我在我的默认用户的住目录下建立服务器目录:

10.Redis编程入门_第5张图片
建立服务器安装目录

创建三个目录:
  | - bin:用来存放执行文件,包含服务器程序,客户程序等。
  | - etc:用来存放配置文件。
  | - db:用来存放数据库文件。

10.Redis编程入门_第6张图片
三个存放目录

1.2. 拷贝执行与配置文件到服务目录

cp ~yangqiang/Downloads/redis-5.0.3/src/mkreleasehdr.sh ./bin
cp ~yangqiang/Downloads/redis-5.0.3/src/redis-benchmark  ./bin/
cp ~yangqiang/Downloads/redis-5.0.3/src/redis-cli  ./bin/
cp ~yangqiang/Downloads/redis-5.0.3/src/redis-server ./bin/
cp ~yangqiang/Downloads/redis-5.0.3/redis.conf   ./etc/
10.Redis编程入门_第7张图片
核心执行程序

2. 修改配置文件

2.1. 配置IP地址

10.Redis编程入门_第8张图片
配置IP地址

2.2. 配置端口

10.Redis编程入门_第9张图片
配置端口

2.3. 配置后台模式

10.Redis编程入门_第10张图片
配置后台模式

2.4. 配置进程锁文件

10.Redis编程入门_第11张图片
配置进程锁文件

2.5. 配置数据库数量

默认是0,可以使用命令行语句select < dbid > 选择数据库。

10.Redis编程入门_第12张图片
配置数据库数量

2.6. 数据库更新保存条件

其中第一个是秒数,第一个是改变次数,满足这些条件的任何一个就会自定保存或者更新。

10.Redis编程入门_第13张图片
数据库更新条件

2.7. 配置数据库数据是否压缩

10.Redis编程入门_第14张图片
压缩配置

2.8. 配置数据库文件名

10.Redis编程入门_第15张图片
配置数据库文件名

2.9. 配置数据库的存放目录

10.Redis编程入门_第16张图片
数据库存放目录

2.10. 配置登录口令

10.Redis编程入门_第17张图片
配置登录口令

三、启动服务器

启动指令:

./bin/redis-server ./etc/redis.conf 

前面是服务器程序,参数是配置文件。

控制台下启动效果如下:


10.Redis编程入门_第18张图片
服务器启动效果

四、客户端使用

1. 客户端命令行帮助

10.Redis编程入门_第19张图片
客户端帮助

2. 启动客户端

10.Redis编程入门_第20张图片
客户端启动

3. 获取客户端使用帮助

连接上服务器后,使用help指令,可以获取使用帮助

10.Redis编程入门_第21张图片
服务器指令帮助

注意:
  其中help 是help后不停按tab键,会依次出现各种命令。
  help @命令分组 获取每个命令组的帮助。
  
  命令与SQL指令一样,不区分大小写。
  
  为了方便,下面介绍常见的操作。

4. 客户端指令分组

4.1. 连接操作相关的命令

命令 说明
ping 测试连接是否存活如果正常会返回pong
echo 打印
select 切换到指定的数据库,数据库索引号 index 用数字值指定,以 0 作为起始索引值
quit 关闭连接(connection)
auth 简单密码认证

4.2. 服务端相关命令

命令 说明
time 返回当前服务器时间
client list 返回所有连接到服务器的客户端信息和统计数据 参见http://redisdoc.com/server/client_list.html
client kill ip:port 关闭地址为 ip:port 的客户端
save 将数据同步保存到磁盘
bgsave 将数据异步保存到磁盘
lastsave 返回上次成功将数据保存到磁盘的Unix时戳
shundown 将数据同步保存到磁盘,然后关闭服务
info 提供服务器的信息和统计
config resetstat 重置info命令中的某些统计数据
config get 获取配置文件信息
config set 动态地调整 Redis 服务器的配置(configuration)而无须重启,可以修改的配置参数可以使用命令 CONFIG GET * 来列出
config rewrite Redis 服务器时所指定的 redis.conf 文件进行改写
monitor 实时转储收到的请求
slaveof 改变复制策略设置

4.3. 发布订阅相关命令

命令 说明
psubscribe 订阅一个或多个符合给定模式的频道 例如psubscribe news.* tweet.*
publish 将信息 message 发送到指定的频道 channel 例如publish msg "good morning"
pubsub channels 列出当前的活跃频道 例如PUBSUB CHANNELS news.i*
pubsub numsub 返回给定频道的订阅者数量 例如PUBSUB NUMSUB news.it news.internet news.sport news.music
pubsub numpat 返回客户端订阅的所有模式的数量总和
punsubscribe 指示客户端退订所有给定模式。
subscribe 订阅给定的一个或多个频道的信息。例如 subscribe msg chat_room
unsubscribe 指示客户端退订给定的频道。

4.4. 对KEY操作的命令

命令 说明
exists(key) 确认一个key是否存在
del(key) 删除一个key
type(key) 返回值的类型
keys(pattern) 返回满足给定pattern的所有key
randomkey 随机返回key空间的一个
keyrename(oldname, newname) 重命名key
dbsize 返回当前数据库中key的数目
expire 设定一个key的活动时间(s)
ttl 获得一个key的活动时间
move(key, dbindex) 移动当前数据库中的key到dbindex数据库
flushdb 删除当前选择数据库中的所有key
flushall 删除所有数据库中的所有key

4.5. 对String操作的命令

命令 说明
set(key, value) 给数据库中名称为key的string赋予值value
get(key) 返回数据库中名称为key的string的value
getset(key, value) 给名称为key的string赋予上一次的value
mget(key1, key2,…, key N) 返回库中多个string的value
setnx(key, value) 添加string,名称为key,值为value
setex(key, time, value) 向库中添加string,设定过期时间time
mset(key N, value N) 批量设置多个string的值
msetnx(key N, value N) 如果所有名称为key i的string都不存在
incr(key) 名称为key的string增1操作
incrby(key, integer) 名称为key的string增加integer
decr(key) 名称为key的string减1操作
decrby(key, integer) 名称为key的string减少integer
append(key, value) 名称为key的string的值附加value
substr(key, start, end) 返回名称为key的string的value的子串

4.6. 对List操作的命令

命令 说明
rpush(key, value) 在名称为key的list尾添加一个值为value的元素
lpush(key, value) 在名称为key的list头添加一个值为value的 元素
llen(key) 返回名称为key的list的长度
lrange(key, start, end) 返回名称为key的list中start至end之间的元素
ltrim(key, start, end) 截取名称为key的list
lindex(key, index) 返回名称为key的list中index位置的元素
lset(key, index, value) 给名称为key的list中index位置的元素赋值
lrem(key, count, value) 删除count个key的list中值为value的元素
lpop(key) 返回并删除名称为key的list中的首元素
rpop(key) 返回并删除名称为key的list中的尾元素
blpop(key1, key2,… key N, timeout) lpop命令的block版本。
brpop(key1, key2,… key N, timeout) rpop的block版本。
rpoplpush(srckey, dstkey) 返回并删除名称为srckey的list的尾元素,并将该元素添加到名称为dstkey的list的头部

4.7. 对Set操作的命令

命令 说明
sadd(key, member) 向名称为key的set中添加元素member
srem(key, member) 删除名称为key的set中的元素member
spop(key) 随机返回并删除名称为key的set中一个元素

smove(srckey, dstkey, member) :移到集合元素
scard(key) |返回名称为key的set的基数
sismember(key, member) |member是否是名称为key的set的元素
sinter(key1, key2,…key N) |求交集
sinterstore(dstkey, (keys)) |求交集并将交集保存到dstkey的集合
sunion(key1, (keys)) |求并集
sunionstore(dstkey, (keys)) |求并集并将并集保存到dstkey的集合
sdiff(key1, (keys)) |求差集
sdiffstore(dstkey, (keys)) |求差集并将差集保存到dstkey的集合
smembers(key) |返回名称为key的set的所有元素
srandmember(key) |随机返回名称为key的set的一个元素

4.8. 对Hash操作的命令

命令 说明
hset(key, field, value) 向名称为key的hash中添加元素field
hget(key, field) 返回名称为key的hash中field对应的value
hmget(key, (fields)) 返回名称为key的hash中field i对应的value
hmset(key, (fields)) 向名称为key的hash中添加元素field
hincrby(key, field, integer) 将名称为key的hash中field的value增加integer
hexists(key, field) 名称为key的hash中是否存在键为field的域
hdel(key, field) 删除名称为key的hash中键为field的域
hlen(key) 返回名称为key的hash中元素个数
hkeys(key) 返回名称为key的hash中所有键
hvals(key) 返回名称为key的hash中所有键对应的value
hgetall(key) 返回名称为key的hash中所有的键(field)及其对应的value

5. 设置密码

设置密码的命令是属于服务器组,其中密码设置属于redis.conf文件中的配置。

10.Redis编程入门_第22张图片
密码设置帮助

可以使用config get指令得到配置参数。
也可以使用config set指令修改配置参数。(当然可以直接编辑redis.conf文件来设置登录密码)

下面首先查看登录密码,然后设置登录密码,然后再登录,登录后就可以查看登录密码了。


10.Redis编程入门_第23张图片
密码设置与登录

强烈推荐登录方式不要使用命令行参数,而是使用AUTH指令。


建议不要使用命令行设置登录密码

6. 选择当前数据库

使用select 指令,指定数据库编号即可。

10.Redis编程入门_第24张图片
切换数据库

7. 数据库操作

7.1. 数据类型

Redis支持五种数据类型:string(字符串),hash(哈希),list(列表),set(集合)及sorted set(有序集合)。

7.2. string数据操作

string 是 redis 最基本的类型,一个 key 对应一个 value;string 类型的值最大能存储 512MB。
string 类型是二进制安全的,就是redis 的 string 可以包含任何数据。比如jpg图片或者序列化的对象。

127.0.0.1:6379> help SET

  SET key value [expiration EX seconds|PX milliseconds] [NX|XX]
  summary: Set the string value of a key
  since: 1.0.0
  group: string

SET参数说明:
  | - EX指定过期时间单位为:秒
  | - PX指定过期时间单位为:毫秒
  | - NX key不存在才执行指令
  | - XX key存在才会更新

String类型操作

过期时间一到,从内存数据消失。

7.3. Hash数据操作

Redis hash 是一个键值(key=>value)对集合。
Redis hash 是一个 string 类型的 field 和 value 的映射表,hash 特别适合用于存储对象。
每个 hash 可以存储 232 -1 键值对(40多亿)。

127.0.0.1:6379> help hmset

  HMSET key field value [field value ...]
  summary: Set multiple hash fields to multiple values
  since: 2.0.0
  group: hash

127.0.0.1:6379> 

10.Redis编程入门_第25张图片
hash类型操作

获取所有keys与values:


10.Redis编程入门_第26张图片
回去所有的keys与values

7.4. List数据操作

Redis 列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边)。
列表最多可存储 232 - 1 元素 (4294967295, 每个列表可存储40多亿)。

10.Redis编程入门_第27张图片
List数据类型操作

7.5. Set数据操作

Redis的Set是string类型的无序集合。
集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是O(1)。

10.Redis编程入门_第28张图片
Set类型操作

7.6. sorted set数据操作

Redis zset(sorted set) 和 set 一样也是string类型元素的集合,且不允许重复的成员。
不同的是每个元素都会关联一个double类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序。
zset的成员是唯一的,但分数(score)却可以重复。

10.Redis编程入门_第29张图片
Sorted-Set类型操作

7.7. 查看key并删除key

使用keys命令与del命令


10.Redis编程入门_第30张图片
Keys操作

7.8. 事务处理

事务命令 说明
DISCARD 取消事务,放弃执行事务块内的所有命令。
EXEC 执行所有事务块内的命令。
MULTI 标记一个事务块的开始。
UNWATCH 取消 WATCH 命令对所有 key 的监视。
WATCH key [key ...] 监视一个(或多个) key ,如果在事务执行之前这个(或这些) key 被其他命令所改动,那么事务将被打断。
10.Redis编程入门_第31张图片
事务操作

五、python访问Redis数据库

1. 安装redis模块

使用命令

yangqiangdeMacBook-Pro:bin yangqiang$ pip install redis
Collecting redis
  Downloading https://files.pythonhosted.org/packages/f1/19/a0282b77c23f9f9dbcc6480787a60807c78a45947593a02dbf026636c90d/redis-3.1.0-py2.py3-none-any.whl (63kB)
    100% |████████████████████████████████| 71kB 103kB/s 
Installing collected packages: redis
Successfully installed redis-3.1.0

Redis模块安装

2. redis模块帮助

使用help可以获取redis模块帮助文档


10.Redis编程入门_第32张图片
Redis模块的帮助

3. redis模块核心API

Redis类负责用户客户端调用的封装,其成员基本上对用Redis客户端的所有操作指令。
Connection负责连接Redis服务器。
其他还有负责分布式锁的Lock等,Sentinel负责集群客户端调用封装等。

4. 单一连接

直接使用Redis连接Redis服务器,redis.client.Redis类构造器如下:

__init__(self, host='localhost', port=6379, db=0, password=None, socket_timeout=None, socket_connect_timeout=None, socket_keepalive=None, socket_keepalive_options=None, connection_pool=None, unix_socket_path=None, encoding='utf-8', encoding_errors='strict', charset=None, errors=None, decode_responses=False, retry_on_timeout=False, ssl=False, ssl_keyfile=None, ssl_certfile=None, ssl_cert_reqs='required', ssl_ca_certs=None, max_connections=None)
# coding = utf-8
import redis.client
redis = redis.client.Redis(host='127.0.0.1', port=6379, db=0, password='yq123456')
print(redis.keys(pattern='*'))

[b'telno', b'key2', b'friends', b'courses', b'key1']

5. 连接池

连接池redis.connection.ConnectionPool的构造器:

__init__(self, connection_class=, max_connections=None, **connection_kwargs)
# coding = utf-8
import redis.client
import redis.connection
pools = redis.connection.ConnectionPool(
    connection_class=redis.connection.Connection,
    max_connections=10,
    host='127.0.0.1',
    port=6379,
    db=0,
    password='yq123456')
redis = redis.client.Redis(connection_pool=pools)
print(redis.keys(pattern='*'))

[b'telno', b'key2', b'friends', b'courses', b'key1']

6. 数据库操作

数据库操作基本上对应redis-cli客户端的指令。

# coding = utf-8
import redis.client
redis = redis.client.Redis(host='127.0.0.1', port=6379, db=0, password='yq123456')
if redis.set(name='py_user', value='Jack'):
    print('执行成功')

if redis.save():
    print('执行成功')



执行成功
执行成功

7. 事务操作

一般来说,事务有四个性质称为ACID,分别是原子性,一致性,隔离性和持久性。
  a)原子性atomicity:redis事务保证事务中的命令要么全部执行要不全部不执行。有些文章认为redis事务对于执行错误不回滚违背了原子性,是偏颇的。
  
  b)一致性consistency:redis事务可以保证命令失败的情况下得以回滚,数据能恢复到没有执行之前的样子,是保证一致性的,除非redis进程意外终结。
  
  c)隔离性Isolation:redis事务是严格遵守隔离性的,原因是redis是单进程单线程模式,可以保证命令执行过程中不会被其他客户端命令打断。
  
  d)持久性Durability:redis事务是不保证持久性的,这是因为redis持久化策略中不管是RDB还是AOF都是异步执行的,不保证持久性是出于对性能的考虑。
  

在Redis中事务有专门的指令,但在Python实现中,通过Pipeline类实现事务相关指令。


__init__(self, connection_pool, response_callbacks, transaction, shard_hint)

获取通过Redis对象的ipieline函数返回Pipeline对象


Redis.pipeline(self, transaction=True, shard_hint=None)

pipeline 也可以保证缓冲的命令组做为一个原子操作。缺省就是这种原子模式。
要使用命令缓冲,但禁止pipeline 的原子操作属性,可以关掉 transaction=False。

7.1. 提交事务

# coding = utf-8

import redis.client
redis = redis.client.Redis(host='127.0.0.1', port=6379, db=0, password='yq123456')
pipeline = redis.pipeline(transaction=True)  # 参数指定是否每个指令后自动提交事务。
pipeline.multi()
pipeline.set(name='py_user', value='Jack')
if pipeline.execute():
    print('提交事务成功')

提交事务成功
# coding = utf-8

import redis.client
import redis.connection
pool = redis.connection.ConnectionPool(max_connections=10, host='127.0.0.1', port=6379, db=0, password='yq123456')
pipe = redis.client.Pipeline(
    connection_pool=pool,
    transaction=True,
    shard_hint=None,
    response_callbacks=[]
)
pipe.multi()
pipe.set(name='py_user', value='Jack')
pipe.set(name='linux_user',value='root')
if pipe.execute():     # 提交事务
    print('事务提交成功!')
事务提交成功!

7.2. 回滚(放弃)事务

  
注意:
  Redis与mysql中事务不同,在redis事务遇到执行错误的时候,不会进行回滚,而是简单的越过了,并保证其他的命令正常执行。这点可以通过上面的程序观察到这个设计效果。
  
  在Python代码中,执行错误的命令的异常会被扑捉,并在execute函数的返回值列表中。

# coding = utf-8

import redis.client
import redis.connection
pool = redis.connection.ConnectionPool(max_connections=10, host='127.0.0.1', port=6379, db=0, password='yq123456')
pipe = redis.client.Pipeline(
    connection_pool=pool,
    transaction=True,
    shard_hint=None,
    response_callbacks=[]
)
pipe.multi()
pipe.set(name='py_user', value='Jack')
pipe.set(name='linux_user',value='root')
# pipe.execute()
pipe.reset()   # 取消事务

注意:
  reset会释放占用的连接,如果使用连接池,则连接会返回到连接池。

7.3. watch与unwatch的使用

  
  在redis-cli终端中,WATCH 命令可以为 Redis 事务提供 check-and-set (CAS)行为。被 WATCH 的键会被监视,并会发觉这些键是否被改动过了。 如果有至少一个被监视的键在 EXEC 执行之前被修改了, 那么整个事务都会被取消, EXEC 返回空多条批量回复(null multi-bulk reply)来表示事务已经失败。
  
  如果在 WATCH 执行之后, EXEC 执行之前, 有其他客户端修改了 WATCH中指定的key的值, 那么程序的事务就会抛出异常 redis.WatchError。抛出异常事务自动取消,需要重新调用MULTI指令。
  
  下面例子运行的时候,在睡眠20秒后指定EXEC,在这期间内,可以在另外客户端修改key为py_user的值,当睡眠20秒后,会抛出异常。(在睡眠中,不会中断睡眠抛出异常,这个与其他编程有差异)
  
  一般对事务处理模式,最好开启监听机制,这样可以提供更好的原子操作。一旦异常抛出,可以反复执行,直到成功为止。

# coding = utf-8

import redis
import redis.connection
import time
pool = redis.connection.ConnectionPool(max_connections=10, host='127.0.0.1', port=6379, db=0, password='yq123456')
pipe = redis.client.Pipeline(
    connection_pool=pool,
    transaction=True,
    shard_hint=None,
    response_callbacks=[]
)
try:
    pipe.watch('py_user',)
    pipe.multi()
    pipe.set(name='py_user', value='Jack')
    time.sleep(20)
    pipe.set(name='linux_user', value='root')
    pipe.execute()
except redis.WatchError as e:
    print(e)
    # 异常抛出的时候,事务被自动取消(注意睡眠期间不会触发异常事件)
    pipe.reset()

Watched variable changed.

7.4. Redis类中transaction函数的使用

  
  上面使用watch来观察key的值被其他客户改变,一般为了防止数据脏,会采用循环方式,Redis类提供了transaction函数来处理这种麻烦。
  
  下面代码,可以在其他客户端改变,会看到print("睡眠")执行两次,直到处理并事务提交成功。

# coding = utf-8
import redis.connection
import time
r = redis.client.Redis(host='127.0.0.1', port=6379, db=0, password='yq123456')


def my_cb(pipe_):
    pipe_.multi()
    pipe_.set(name='py_user', value='Jack-Hello')
    print("睡眠")
    time.sleep(5)
    pipe_.set(name='linux_user', value='root')
    if pipe_.execute():
        print("提交成功")
    else:
        print("提交失败")


r.transaction(my_cb, 'py_user')

睡眠
睡眠
提交成功





[]

8. Pipeline类命令执行回调实现

  Pipeline类的构造器中可以指定对命令执行结果返回的回调,这样可以每个命令被执行就可以及时响应,而不是处理execute的返回结果。
  回调函数至少传递一个参数,如果有withscores这样的参数,可能返回多个参数。

# coding = utf-8

import redis
import redis.connection
import time


# 返回每个命名执行的结果
def my_call(*p):
    print(*p)


pool = redis.connection.ConnectionPool(max_connections=10, host='127.0.0.1', port=6379, db=0, password='yq123456')
pipe = redis.client.Pipeline(
    connection_pool=pool,
    transaction=True,
    shard_hint=None,
    response_callbacks={'SET': my_call}
)
pipe.multi()
pipe.set(name='py_user', value='Jack')
pipe.set(name='linux_user', value='root')
pipe.execute()    # 因为有回调,所以,这个函数返回是None。


b'OK'
b'OK'





[None, None]

9. 订阅与发布

订阅与发布是一种消息通信机制。包含两个行为:
   | - 订阅:SUBSCRIBE channel [channel ...]
   | - 发布:PUBLISH channel message
  
当然可以退订。
   |- 退订:UNSUBSCRIBE [channel [channel ...]]
同时提供模式匹配指令:
   |- PSUBSCRIBE pattern [pattern ...]
   |- PUNSUBSCRIBE [pattern [pattern ...]]
查看订阅状态:
   |- PUBSUB subcommand [argument [argument ...]]

9.1. 订阅消息

使用SUBSCRIBE命令订阅消息:

10.Redis编程入门_第33张图片
消息订阅

9.2. 发布消息

使用PUBLISH发布消息:


10.Redis编程入门_第34张图片
消息发布

9.3. 查看订阅发布状态

9.3.1. 获取帮助

使用PUBSUB HELP命令获取完整的帮助:


10.Redis编程入门_第35张图片
消息状态查看指令帮助

9.3.2. 查看订阅状态

注意:
  NUMPAT是采用模式订阅的数量。
  NUMSUB是多某个频道德订阅数量。

10.Redis编程入门_第36张图片
消息状态查看操作

9.4. 使用python程序订阅消息

订阅消息需要使用订阅发布对象class 'redis.client.PubSub'。
调用handle_message可以把订阅的响应结构解析成一个字典结构。

# coding = utf-8
import redis.client

redis = redis.client.Redis(host='127.0.0.1', port=6379, db=0, password='yq123456')
sub_pub = redis.pubsub()
print(sub_pub, type(sub_pub))

sub_pub.subscribe('mychannel')

result = sub_pub.parse_response()
print('订阅操作:', result)
result = sub_pub.parse_response()
message = sub_pub.handle_message(result)
print('订阅的消息:', result, message['data'])

 
订阅操作: [b'subscribe', b'mychannel', 1]
订阅的消息: [b'message', b'mychannel', b'this is a test message'] b'this is a test message'

9.5. 使用python程序发布消息

# coding = utf-8
import redis.client

redis = redis.client.Redis(host='127.0.0.1', port=6379, db=0, password='yq123456')
redis.publish('mychannel','this is a test message')

4

六、附录

  Redis还有一些其他连接快捷方式,我们采用比较常规的方式介绍。
  Redis还支持集群,后面单独介绍集群的配置与Python编程的一些基本概念。

你可能感兴趣的:(10.Redis编程入门)