Redis

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 可以省略,如果省略,会启用默认的。输入之后,会显示如下界面:

Redis 安装

这时候另启一个 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"))#0 conn.expire('name',2) #为给定 key 设置过期时间,以秒计 print(conn.exists('name'))#1 conn.mset({"key1":"v1","key2":"v2"}) print(conn.mget(["key1","key2"]))#['v1', 'v2'] conn.hset("xiaoming","hobby","1") print(conn.hget("xiaoming","hobby"))#1 conn.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 json
my_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 redis
pool = redis.ConnectionPool(host="localhost",port=6379,decode_responses =True,max_connections=5)
import redis
from utils.redis_pool import pool
conn = 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.loads

1. 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 pool
import  redis
conn = 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 redis
from utils.redis_pool import pool
conn = redis.Redis(connection_pool=pool)
conn.publish("xiayuhao","ladyboy")

订阅者

import redis
from utils.redis_pool import pool
conn = redis.Redis(connection_pool=pool)
#生成一个订阅者对象
pubsub = conn.pubsub()
#监听建 pubsub.subscribe(
"xiayuhao") while True: print("ddddddddddddd") msg = pubsub.parse_response() print(msg)

 

posted @ 2018-12-21 16:30  从入门到出师  阅读(171)  评论(0编辑  收藏  举报