python操作redis

REmote DIctionary Server(Redis) 是一个由Salvatore Sanfilippo写的key-value存储系统。

Redis是一个开源的使用ANSI C语言编写、遵守BSD协议、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。

它通常被称为数据结构服务器,因为值(value)可以是 字符串(String), 哈希(Hash), 列表(list), 集合(sets) 和 有序集合(sorted sets)等类型。

Redis 简介

Redis 是完全开源免费的,遵守BSD协议,是一个高性能的key-value数据库。

Redis 与其他 key - value 缓存产品有以下三个特点:

  • Redis支持数据的持久化,可以将内存中的数据保存在磁盘中,重启的时候可以再次加载进行使用。
  • Redis不仅仅支持简单的key-value类型的数据,同时还提供list,set,zset,hash等数据结构的存储。
  • Redis支持数据的备份,即master-slave模式的数据备份。

Redis 优势

  • 性能极高 – Redis能读的速度是110000次/s,写的速度是81000次/s 。
  • 丰富的数据类型 – Redis支持二进制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 数据类型操作。
  • 原子 – Redis的所有操作都是原子性的,意思就是要么成功执行要么失败完全不执行。单个操作是原子性的。多个操作也支持事务,即原子性,通过MULTI和EXEC指令包起来。
  • 丰富的特性 – Redis还支持 publish/subscribe, 通知, key 过期等等特性。

安装Redis

windows安装:

下载地址:https://github.com/tporadowski/redis/releases

直接下一步一步就可以了

LInux下安装:

  • centos:
1
2
3
4
5
# 安装
yum install redis -y
# 当然没有权限的时候记得加sudo
# 启动
redis-server
  • untubu
1
2
3
4
5
# 安装
apt-get update
apt-get install redis
# 启动
redis-server

编译安装

1
2
3
4
$ wget http://download.redis.io/releases/redis-6.0.4.tar.gz
$ tar xzf redis-6.0.4.tar.gz
$ cd redis-6.0.4
$ make

src 目录 中现在提供了已编译的二进制文件 。使用以下命令运行Redis:

1
$ src/redis-server

当然这些都是运维会配置好的,我们了解即可

Python安装 redis 模块

Python 要使用 redis,需要先安装 redis 模块:

1
pip3 install redis

redis 提供两个类 Redis 和 StrictRedis, StrictRedis 用于实现大部分官方的命令,Redis 是 StrictRedis 的子类,用于向后兼用旧版本。

redis 取出的结果默认是字节,我们可以设定 decode_responses=True 改成字符串。

1
2
3
4
5
6
import redis   # 导入redis 模块
r = redis.Redis(host='localhost', port=6379, decode_responses=True)
r.set('name', 'runoob') # 设置 name 对应的值
print(r['name'])
print(r.get('name')) # 取出键 name 对应的值
print(type(r.get('name'))) # 查看类型

连接池

redis-py 使用 connection pool 来管理对一个 redis server 的所有连接,避免每次建立、释放连接的开销。

默认,每个Redis实例都会维护一个自己的连接池。可以直接建立一个连接池,然后作为参数 Redis,这样就可以实现多个 Redis 实例共享一个连接池。

1
2
3
4
5
6
import redis    # 导入redis 模块

pool = redis.ConnectionPool(host='localhost', port=6379, decode_responses=True)
r = redis.Redis(connection_pool=pool)
r.set('name', 'runoob') # 设置 name 对应的值
print(r.get('name')) # 取出键 name 对应的值

常用命令

redis基本命令 String

set(name, value, ex=None, px=None, nx=False, xx=False)

在Redis中设置值,默认,不存在则创建,存在则修改
参数:

  • ex,过期时间(秒)
  • px,过期时间(毫秒)
  • nx,如果设置为True,则只有name不存在时,当前set操作才执行
  • xx,如果设置为True,则只有name存在时,当前set操作才执行
1
2
3
4
r.set('k','v',ex=2)
print(r.get('k')) 'v'
time.sleep(3)
print(r.get('k')) None

mset(*args, **kwargs):批量设置值

1
2
3
4
r.mget({'k1': 'v1', 'k2': 'v2'})
r.mset(k1="v1", k2="v2") # 这里k1 和k2 不能带引号 一次设置对个键值对
print(r.mget("k1", "k2")) # 一次取出多个键对应的值
print(r.mget("k1"))

mget(keys, *args):批量获取

1
2
3
print(r.mget('k1', 'k2'))
print(r.mget(['k1', 'k2']))
print(r.mget("fruit", "fruit1", "fruit2", "k1", "k2")) # 将目前redis缓存中的键对应的值批量取出来

getset(name, value):设置新值并获取原来的值

1
print(r.getset("food", "barbecue"))  # 设置的新值是barbecue 设置前的值是beef

redis基本命令 hash

hset(name, key, value)

单个增加—修改(单个取出)—没有就新增,有的话就修改

name对应的hash中设置一个键值对(不存在,则创建;否则,修改)
参数:

  • name,redis的name
  • key,name对应的hash中的key
  • value,name对应的hash中的value

注:
hsetnx(name, key, value),当name对应的hash中不存在当前key时则创建(相当于添加)

1
2
3
4
5
6
7
r.hset("hash1", "k1", "v1")
r.hset("hash1", "k2", "v2")
print(r.hkeys("hash1")) # 取hash中所有的key
print(r.hget("hash1", "k1")) # 单个取hash的key对应的值
print(r.hmget("hash1", "k1", "k2")) # 多个取hash的key对应的值
r.hsetnx("hash1", "k2", "v3") # 只能新建
print(r.hget("hash1", "k2"))

hmset(name, mapping)批量增加(取出)

在name对应的hash中批量设置键值对
参数:

  • name,redis的name
  • mapping,字典,如:{‘k1’:’v1’, ‘k2’: ‘v2’}
1
r.hmset("hash2", {"k2": "v2", "k3": "v3"})

hget(name,key)在name对应的hash中获取根据key获取value

hmget(name, keys, *args) 在name对应的hash中获取多个key的值

参数:

  • name,reids对应的name
  • keys,要获取key集合,如:[‘k1’, ‘k2’, ‘k3’]
  • *args,要获取的key,如:k1,k2,k3
1
2
3
print(r.hget("hash2", "k2"))  # 单个取出"hash2"的key-k2对应的value
print(r.hmget("hash2", "k2", "k3")) # 批量取出"hash2"的key-k2 k3对应的value --方式1
print(r.hmget("hash2", ["k2", "k3"])) # 批量取出"hash2"的key-k2 k3对应的value --方式2

hgetall(name)取出所有的键值对

1
print(r.hgetall("hash1"))

hexists(name, key)判断成员是否存在(类似字典的in)

检查name对应的hash是否存在当前传入的key

1
2
print(r.hexists("hash1", "k4"))  # False 不存在
print(r.hexists("hash1", "k1")) # True 存在

hdel(name,*keys)删除键值对

将name对应的hash中指定key的键值对删除

1
2
3
4
5
print(r.hgetall("hash1"))
r.hset("hash1", "k2", "v222") # 修改已有的key k2
r.hset("hash1", "k11", "v1") # 新增键值对 k11
r.hdel("hash1", "k1") # 删除一个键值对
print(r.hgetall("hash1"))

redis基本命令 list

lpush(name,values) 左添加 &rpush右添加

1
2
r.lpush("list1", 11, 22, 33)    # 在列表的左边,依次添加11,22,33
r.rpush("list2", 44, 55, 66) # 在列表的右边,依次添加44,55,66

lpushx(name,value) 存在才添加左边 &rpushx(name,value) 存在才添加右边

1
2
3
4
5
6
7
8
9
r.lpushx("list10", 10)   # 这里list10不存在
print(r.llen("list10")) # 0
print(r.lrange("list10", 0, -1)) # []
r.lpushx("list2", 77) # 这里"list2"之前已经存在,往列表最左边添加一个元素,一次只能添加一个
print(r.llen("list2")) # 列表长度
print(r.lrange("list2", 0, -1)) # 切片取出值,范围是索引号0到-1(最后一个元素
r.rpushx("list2", 99) # 这里"foo_list1"之前已经存在,往列表最右边添加一个元素,一次只能添加一个
print(r.llen("list2")) # 列表长度
print(r.lrange("list2", 0, -1)) # 切片取出值,范围是索引号0到-1(最后一个元素)

linsert(name, where, refvalue, value))新增(固定索引号位置插入元素)

在name对应的列表的某一个值前或后插入一个新值
参数:

  • name,redis的name
  • where,BEFORE或AFTER
  • refvalue,标杆值,即:在它前后插入数据
  • value,要插入的数据
1
2
r.linsert("list2", "before", "11", "00")   # 往列表中左边第一个出现的元素"11"前插入元素"00"
print(r.lrange("list2", 0, -1)) # 切片取出值,范围是索引号0-最后一个元素

r.lset(name, index, value)修改(指定索引号进行修改)

对name对应的list中的某一个索引位置重新赋值
参数:

  • name,redis的name
  • index,list的索引位置
  • value,要设置的值
1
2
r.lset("list2", 0, -11)    # 把索引号是0的元素修改成-11
print(r.lrange("list2", 0, -1))

r.lrem(name, value, num)删除(指定值进行删除)

在name对应的list中删除指定的值
参数:

  • name,redis的name
  • value,要删除的值
  • num, num=0,删除列表中所有的指定值;
  • num=2,从前到后,删除2个; num=1,从前到后,删除左边第1个
  • num=-2,从后向前,删除2个
1
2
3
4
5
6
r.lrem("list2", "11", 1)    # 将列表中左边第一次出现的"11"删除
print(r.lrange("list2", 0, -1))
r.lrem("list2", "99", -1) # 将列表中右边第一次出现的"99"删除
print(r.lrange("list2", 0, -1))
r.lrem("list2", "22", 0) # 将列表中所有的"22"删除
print(r.lrange("list2", 0, -1))

lpop(name)删除并返回

在name对应的列表的左侧获取第一个元素并在列表中移除,返回值则是第一个元素

  • rpop(name) 表示从右向左操作
1
2
3
4
r.lpop("list2")    # 删除列表最左边的元素,并且返回删除的元素
print(r.lrange("list2", 0, -1))
r.rpop("list2") # 删除列表最右边的元素,并且返回删除的元素
print(r.lrange("list2", 0, -1))

lindex(name, index)取值(根据索引号取值)

在name对应的列表中根据索引获取列表元素

1
print(r.lindex("list2", 0))  # 取出索引号是0的值

具体操作可以参考 :https://www.jianshu.com/p/2639549bedc8

常用其实就那么几个get.set.hget,gset