Redis快速上手教程

熊大2022年5月24日大约 10 分钟

Redis

[TOC]

终极策略:使用Redis的String类型做的事,都可以用Memcached替换,以此换取更好的性能提升; 除此以外,优先考虑Redis

Redis安装和启动

安装

Linux的安装:apt install redis-server

Windows安装:windows解压包open in new window

直接运行.zip包内的redis-cli.exe文件连接到本地服务器

启动

Windows下启动Redis服务器:

  1. 如果是通过.msi安装的会自动的通过服务启动Redis服务
  2. 如果是通过.zip解压的直接手动运行redis-server.exe启动服务

linux下启动Redis服务器:

# 启动Redis服务器
systemctl restart redis
# 查看redis是否开启
ps -ef | grep redis
# 启动Redis客户端
redis-cli
# 手动重启服务
redis-cli shutdown
redis-server /etc/redis/redis.conf

配置

配置密码

#>>> vim /etc/redis.conf

# 去掉前面的注释,并修改后面的密码
requirepass passwd123
  1. 使用密码登陆redis:

redis-cli -h 127.0.0.1 -p 6379 -a passwd123

不添加-a参数虽然也可以登录成功,但是没有任何操作权限。需要使用auth myPassword登陆。

  1. 登陆后查看密码:

    config get requirepass

  2. 在命令行临时修改密码:

    config set requirepass newPassword

  3. 在Redis集群中使用认证密码

    如果Redis服务器,使用了集群。除了在master中配置密码外,也需要在slave中进行相应配置。在slave的配置文件中找到如下行,去掉注释并修改与master相同的密码即可:

    # masterauth master-password
    

Redis数据类型

  1. 字符串 String
  2. 散列/哈希 Hash
  3. 列表 List
  4. 集合 Set
  5. 可排序集合 ZSet
  6. 位图 Bitmap

命令

常用命令

# 查看所有的变量
keys *
# 查看某个变量类型
type username
# 清空所有数据
flushall

字符串命令

# 设置键/值
set username "xionglilong"
# 得到某个键的值
get username
# 得到某个键的子串
getrange username 2 5
# 得到键长度
strlen username  

set count "3"
# 给键加1
incr count
# 给键减1
decr count
# 给字符串附加其他字符串
append count "xiong"

哈希命令

# 在username_dict字典里,设置键为'xiong',值为'xionglilong'
hset username_dict xiong "xionglilong"
# 得到username_dict字典中xiong的值
hset username_dict xiong
# 得到username_dict字典中所有键值对
hgetall username_dict
# 判断username_dict字典中xiong键是否存在
hexists username_dict xiong
# 删除username_dict字典中xiong这个键
hdel username_dict xiong
# 获取username_dict字典中所有键
hkeys username_dict
# 获取username_dict字典中所有值
hvals username_dict

列表命令

# 向username_list列表左边添加"xiong"这个值
lpush username_list "xiong"
# 向username_list列表右边添加"zhang"这个值
rpush username_list "zhang"
# 获取0-10的位置的值
lrange username_list 0 10 
# 从列表左侧弹出一个值,超时时间为3秒,b=block(阻塞),brpop为右侧
blpop username_list 3
# 从列表右侧弹出一个值(非阻塞,没有就返回)
rpop username_list
# 列表的长度
llen username_list
# 取出username_list列表的第一元素
lindex username_list 0

集合命令

#在username_set集合内添加一个元素(不可重复)
sadd username_set "xiong"
# 获取元素总数
scard username_set 
# 前面的set减去后面的set
sdiff username_set username2_set
# 两个set求交集
sinter username_set username2_set
# 随机弹出一个值
spop username_set
# 随机获取三个值
srandmember username_set 3
# # 获取集合所有元素
smembers username_set

可排序集合

# 向username_set集合添加值并设置值的分数
zadd username_set 0 "xiong" 5 "zhang" 10 "huang"
# 获取username_set集合中0-5分的值
zrangebyscore username_set 0 5
# 获取username_set集合0-5分的值的总数
zcount username_set 0 5

python调用

pip install redis

连接

import redis

# 第一种方式连接:(会自动创建连接池,推荐使用)
r = redis.Redis(host='127.0.0.1', port=6379, password='ps123', db=0, decode_responses=True)

# 第二种方式连接: (手动创建连接池)
redis_pool = redis.ConnectionPool(host='127.0.0.1', port=6379, password='ps123', db=0, decode_response=true)  # 建立redis连接池
r = redis.Redis(connection_pool=pool) 

当程序创建数据源实例时,系统会一次性创建多个数据库连接,并把这些数据库连接保存在连接池中,当程序需要进行数据库访问时,无需重新新建数据库连接,而是从连接池中取出一个空闲的数据库连接。实现多个Redis实例共享一个连接池。 目前新版中初始化默认就定义了连接池,可以不自己定义 **注意:**默认情况下,设置的值或取得的值都为bytes类型,如果想改为str类型,需要在连接时添加上decode_responses=True db=0: redis有0-15 共计16个数据库 默认是0 可以根据不同类型数据存放到不同的数据库下

python redis基本操作

提示

常见参数:

  • nx: 仅新建,如果不存在该键才执行
  • xx: 仅修改,如果键存在才执行

管道

日常使用中一般不会用到管道

一般情况下,执行一条命令后必须等待结果才能输入下一次命令,管道用于在一次请求中执行多个命令。

redis-py默认在执行每次请求都会创建(连接池申请连接)和断开(归还连接池)一次连接操作。

如果想要在一次请求中指定多个命令,则可以使用pipline实现一次请求指定多个命令,并且默认一次pipline 是原子性操作。

transaction:指示是否所有的命令应该以原子方式执行,要使用命令缓冲,但禁止pipeline 的原子操作属性,关掉 transaction(transaction=False

import redis
pool = redis.ConnectionPool(host='192.168.0.110', port=6379)
r = redis.Redis(connection_pool=pool)

pipe = r.pipeline(transaction=True)

r.set('name', 'zhangsan')
r.set('name', 'lisi')

pipe.execute()

发布和订阅

首先定义一个RedisHelper类,连接Redis,定义频道为monitor,定义发布(publish)及订阅(subscribe)方法。

import redis

class RedisHelper(object):
    def __init__(self):
        self.__conn = redis.Redis(host='192.168.0.110',port=6379)#连接Redis
        self.channel = 'monitor' #定义名称

    def publish(self,msg):#定义发布方法
        self.__conn.publish(self.channel,msg)
        return True

    def subscribe(self):#定义订阅方法
        pub = self.__conn.pubsub()
        pub.subscribe(self.channel)
        pub.parse_response()
        return pub

发布者:

#发布
from RedisHelper import RedisHelper

obj = RedisHelper()
obj.publish('hello')#发布

订阅者:

from RedisHelper import RedisHelper

obj = RedisHelper()
redis_sub = obj.subscribe()#调用订阅方法

while True:
    msg= redis_sub.parse_response()
    print (msg)

发布和订阅2

发布方:

import redis
r=redis.Redis(host="localhost",port=6379,decode_responses=True)

#发布使用publish(self, channel, message):Publish ``message`` on ``channel``.
Flag=True
while Flag:
    msg=input("主播请讲话>>:")
    if len(msg)==0:
        continue
    elif msg=='quit':
        break
    else:
        r.publish('cctv0',msg)

订阅方:

import redis
r=redis.Redis(host="localhost",port=6379,decode_responses=True)

#发布使用publish(self, channel, message):Publish ``message`` on ``channel``.
Flag=True
chan=r.pubsub()#返回一个发布/订阅对象
msg_reciver=chan.subscribe('cctv0')#订阅

msg=chan.parse_response()#第一次会返回订阅确认信息
print(msg)
print("订阅成功,开始接收------")
while Flag:
    msg=chan.parse_response()#接收消息
    print(">>:",msg[2])#此处的信息格式['消息类型', '频道', '消息'],所以使用[2]来获取

事务

python中可以使用管道来代替事务:

import redis,time
import redis.exceptions
r=redis.Redis(host='localhost',port=6379,decode_responses=True)
pipe=r.pipeline()
print(r.get('a'))


try:
    # pipe.watch('a')
    pipe.multi()
    pipe.set('here', 'there')
    pipe.set('here1', 'there1')
    pipe.set('here2', 'there2')
    time.sleep(5)
    pipe.execute()

except redis.exceptions.WatchError as e:
    print("Error")