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与其他key-value存储有什么不同?
-
Redis有着更为复杂的数据结构并且提供对他们的原子性操作,这是一个不同于其他数据库的进化路径。Redis的数据类型都是基于基本数据结构的同时对程序员透明,无需进行额外的抽象。
-
Redis运行在内存中但是可以持久化到磁盘,所以在对不同数据集进行高速读写时需要权衡内存,因为数据量不能大于硬件内存。在内存数据库方面的另一个优点是,相比在磁盘上相同的复杂的数据结构,在内存中操作起来非常简单,这样Redis可以做很多内部复杂性很强的事情。同时,在磁盘格式方面他们是紧凑的以追加的方式产生的,因为他们并不需要进行随机访问。
Redis使用
打开一个 cmd 窗口 使用 cd 命令切换目录到 C:\redis 运行:
redis-server.exe redis.windows.conf
如果想方便的话,可以把 redis 的路径加到系统的环境变量里,这样就省得再输路径了,后面的那个 redis.windows.conf 可以省略,如果省略,会启用默认的。输入之后,会显示如下界面:
这时候另启一个 cmd 窗口,原来的不要关闭,不然就无法访问服务端了。
切换到 redis 目录下运行:
redis-cli.exe -h 127.0.0.1 -p 6379
在python中使用Redis
import redis conn =redis.Redis(host='localhost', port=6379,decode_responses=True) #加上decode_responses=True,写入的键值对中的value为str类型,不加这个参数写入的则为字节类型。conn.set('name','xiaoming')print(conn.get('name'))print(conn.exists("we"))#0conn.expire('name',2) #为给定 key 设置过期时间,以秒计print(conn.exists('name'))#1conn.mset({ "key1":"v1","key2":"v2"})print(conn.mget(["key1","key2"]))#['v1', 'v2']conn.hset("xiaoming","hobby","1")print(conn.hget("xiaoming","hobby"))#1conn.hmset("xiaohe",{ "key1":"v1","key2":"v2"})print(conn.hmget("xiaohe",["key1","key2"]))#['v1', 'v2']print(conn.hgetall("xiaohe"))#{'key1': 'v1', 'key2': 'v2'}
# 字符串的操作conn.set('name', 'xiaoming')print(conn.get('name'))conn.mset({'key1': 'v1', 'key2': 'v2'})print(conn.mget(['key1', 'key2']))print(conn.get('key1'))# key操作print(conn.exists('name'))print(conn.exists('age'))conn.expire('name', 5)# Hash操作conn.hset('xiaoming', 'hobby', '吃')print(conn.hget('xiaoming', 'hobby'))conn.hmset('heihei', {'f1': 'v1', 'f2': 'v2'})print(conn.hmget('heihei', ['f1', 'f2']))print(conn.hgetall('heihei'))import jsonmy_dict = { 'hobby1': '吃', 'hobby2': '睡'}ret = json.dumps(my_dict, ensure_ascii=False)conn.hset('xiaohong', 'hobby', ret)print(conn.hget('xiaohong', 'hobby'))print(conn.hgetall('xiaohong'))
Python Redis 连接池
使用connection pool来管理对一个redis server的所有连接,避免每次建立、释放连接的开销。
默认,每个Redis实例都会维护一个自己的连接池。可以直接建立一个连接池,
然后作为参数传给Redis实例,这样就可以实现多个Redis实例共享一个连接池。
import redispool = redis.ConnectionPool(host="localhost",port=6379,decode_responses =True,max_connections=5)
import redisfrom utils.redis_pool import poolconn = redis.Redis(connection_pool=pool)conn.set('name','xiaoming')print(conn.get('name'))
Redis的基本命令
1、关于key的命令1. DEL key该命令用于在 key 存在时删除 key。2. DUMP key 序列化给定 key ,并返回被序列化的值。3. EXISTS key 检查给定 key 是否存在。4. EXPIRE key seconds为给定 key 设置过期时间,以秒计。5. EXPIREAT key timestamp EXPIREAT 的作用和 EXPIRE 类似,都用于为 key 设置过期时间。 不同在于 EXPIREAT 命令接受的时间参数是 UNIX 时间戳(unix timestamp)。6. PEXPIRE key milliseconds 设置 key 的过期时间以毫秒计。7. PEXPIREAT key milliseconds-timestamp 设置 key 过期时间的时间戳(unix timestamp) 以毫秒计2、字符串命令1. SET key value 设置指定 key 的值2. GET key 获取指定 key 的值。3. GETRANGE key start end 返回 key 中字符串值的子字符4. MSET key value [key value ...]同时设置一个或多个 key-value 对。5. MGET key1 [key2..]获取所有(一个或多个)给定 key 的值。3、Hash注意:Hash不支持多次嵌套,即"key": { 'field': '不能再对应字典'}"key": { 'field': {...}} --> 错误 若想嵌套字典,可以json.dumps后存入,取出数据的时候可以json.loads1. HSET key field value 将哈希表 key 中的字段 field 的值设为 value 。2. HGET key field 获取存储在哈希表中指定字段的值。3. HMSET key field1 value1 [field2 value2 ] 同时将多个 field-value (域-值)对设置到哈希表 key 中。4. HMGET key field1 [field2] 获取所有给定字段的值5. HGETALL key 获取在哈希表中指定 key 的所有字段和值6. HDEL key field1 [field2] 删除一个或多个哈希表字段7. HEXISTS key field 查看哈希表 key 中,指定的字段是否存在。
事务
-- redis的命令是原子性
-- redis事物(批量执行)不具有原子性 批量执行操作 一个操作失败不影响其他操作 注意:与mysql事务的区别mysql:开启了事务后,其他命令不能插入进来,如果其中一项命令执行失败,那么在事务里面的所有命令都不会执行成功。(具有原子性)redis:开启了事务后,其他命令不能插入进来,如果其中一项命令执行失败,那么在事务里面的其他命令依旧会执行。(不具有原子性)在python中执行redis事务
from utils.redis_pool import poolimport redisconn = redis.Redis(connection_pool=pool)try: # 初始化事务对象,开启事务 pipe = conn.pipeline() pipe.set("name1", "xiaoming") pipe.set("name2", "xiaohe", "吃饭")#报错 pipe.set("name3", "xa222") # 提交事务,执行操作 pipe.execute()except Exception as e: print(e)print(conn.get("name1"))print(conn.get("name2"))print(conn.get("name3"))
发布订阅
Redis 发布订阅(pub/sub)是一种消息通信模式:发送者(pub)发送消息,订阅者(sub)接收消息。
Redis 客户端可以订阅任意数量的频道。下图展示了频道 channel1 , 以及订阅这个频道的三个客户端 —— client2 、 client5 和 client1 之间的关系:
当有新消息通过 PUBLISH 命令发送给频道 channel1 时, 这个消息就会被发送给订阅它的三个客户端:
发布者
import redisfrom utils.redis_pool import poolconn = redis.Redis(connection_pool=pool)conn.publish("xiayuhao","ladyboy")
订阅者
import redisfrom utils.redis_pool import poolconn = redis.Redis(connection_pool=pool)#生成一个订阅者对象pubsub = conn.pubsub() #监听建pubsub.subscribe("xiayuhao")while True: print("ddddddddddddd") msg = pubsub.parse_response() print(msg)