【新闻推荐系统】(task2)Python调用Redis

本文涉及的产品
云原生内存数据库 Tair,内存型 2GB
云数据库 Redis 版,社区版 2GB
推荐场景:
搭建游戏排行榜
云数据库 MongoDB,独享型 2核8GB
推荐场景:
构建全方位客户视图
简介: 在Python中,目前可以通过一个redis模块来实现操控Redis,下面我们简单的介绍一下关于使用redis模块。

二、Python调用Redis

在Python中,目前可以通过一个redis模块来实现操控Redis,下面我们简单的介绍一下关于使用redis模块。

2.1 安装Redis模块

如果是在Windows 系统,安装 redis 模块可以使用以下命令:

python -m pip install redis

如果是 Linux 系统,需要执行以下命令来安装:

sudo pip3 install redis

如果是使用Anaconda管理环境,也可以使用以下命令安装:

conda install redis

2.2 Python连接Redis

Redis模块提供了两种连接的模式:直连模式和连接词模式。


(1)直连模式

直连模式的方式简单方便,适合少量长期连接的场景。其中host参数是ip地址,如果Redis服务存在于本地,可以使用127.0.0.1,或者换成Redis服务所在的ip地址。db表示当前选择的库,其参数值可以是 0-15;如果设置连接数据库的密码,那么就需要使用password进行验证。

import redis
# 1、直连模式
r = redis.Redis(host = '127.0.0.1', 
                port = 6379, 
                db = 0, 
                password = '12345')
r.set('name', 'jiangyou')
print(r.get('name'))

(2)连接池模式

连接池模式是使用 connection pool(连接池)来管理 redis server 的所有连接,每个Redis实例会维护自己的连接池来管理管理对一个 redis server 所有的连接,避免每次建立,释放连接的开销。

# 2、连接池模式
pool = redis.ConnectionPool(host="127.0.0.1",
                            port=6379,
                            db=0,password="",
                            decode_responses=True, 
                            max_connections=10)
r1 = redis.Redis(connection_pool=pool)   #  第一个客户端访问
r2 = redis.Redis(connection_pool=pool)   #  第二个客户端访问

上面的参数,decode_responses=True 可以使得redis取出的结果改成字符串,其默认的是字节, max_connections参数可以设置最大连接数量,这样当有新的客户端请求连接时,只需要去连接池获取即可,这样就可以把一个连接共享给多个客服端,减少每次连接所消耗的时间以及资源。


2.3 基本操作

在Redis模块中,提供了Redis和StrictRedis来支持Redis访问和操作。其中 StrictRedis 使用python基于Redis协议实现了所有官方的Redis操作命令,也就是说其实对于python操作redis的API接口和上面提到的Redis官方接口一样。因此下面我们就简单介绍一些常用的方法。


1. String操作

import redis
pool = redis.ConnectionPool(host="127.0.0.1",
              port=6379,
              db=0,password="",
              decode_responses=True,
              max_connections=10)
r = redis.StrictRedis(connection_pool=pool)
r.set('name','jiang')
r.append("name","you") # 在redis name对应的值后面追加内容
r.mset({'age':'26','home':'liaoning'})
print(r.mget('name','age','home'))
print("name 长度:%d"%r.strlen('name'))   #查看ame对应值的长度
r.incrby('age',5)   #数值操作  将age对应的值 加5
print(r.get('age'))
r.decrby('age',5)   #数值操作  将age对应的值 减5
print(r.get('age'))
r.incrbyfloat('age',5.2)  #将age对应的值 加5.2
print(r.get('age'))
r.incrbyfloat('age',-10.5)  #将age对应的值 减10.5
print(r.get('age'))
r.setrange('name',5,'hahaha')  # 修改字符串内容,从指定字符串索引开始向后替换。
print(r.getrange('name',0,6))   #  获取子序列(根据字节获取,非字符),闭区间
r.delete('name')  #删除key

运行结果

['jiangyou', '26', 'liaoning']
name 长度:8
31
26
31.2
20.7
jiangha

2. Hash操作

image.pngimage.png

批量操作:image.png

import redis
pool = redis.ConnectionPool(host="127.0.0.1",port=6379,db=0,password="",decode_responses=True,max_connections=10)
r = redis.StrictRedis(connection_pool=pool)
r.hset('user1','name','zhangsan')   # user1对应的hash中设置一个键值对(不存在,则创建;否则,修改)
r.hset('user1','age','22')          # user1对应的hash中设置一个键值对(不存在,则创建;否则,修改)
r.hincrbyfloat('user1','age',0.5)   # 自增user1对应的hash中的指定key的值,不存在则创建key=amount
print(r.hmget('user1','name','age'))  # 在user1对应的hash中获取多个key的值
# 一次性设置多个field和value
user_dict = {
  'password':'123',
  'gender':'M',
  'home':'辽宁'
}
r.hmset('user1',user_dict)        #  在user1对应的hash中批量设置键值对 

如果按照上面的hmset是会报错的:DeprecationWarning: Redis.hmset() is deprecated. Use Redis.hset() instead.所以将hmset()改成hset即可。


【注意】Redis 4.0.0开始弃用HMSET,请使用HSET!!

添加:返回添加数量

修改数值:成功返回0

example:

  Redis> HSET myhash field1 hello 
  (integer)1
  Redis> HSET myhash field2 world field3 goodbye
  (integer)2
  Redis> HSET myhash field3 goodnight
  (integer)0

如果是在python上的redis则可以参考Stack Overflow

   print("user1中存在键值对的个数:%d "%r.hlen('user1')) #  获取所有数据,字典类型
   print("user1中存在键值对的具体信息:%s"%r.hgetall('user1')) #  获取所有数据,字典类型
   print(r.hkeys("user1"))  # 获取所有fields字段
   print(r.hvals("user1"))  # 获取所有fields字段的values值
   if r.hexists("user1","home"):            #  检查user1对应的hash是否存在当前传入的home
       r.hdel("user1",'home')               #  将user1对应的hash中指定key的键值对删除
       print("已删除该键!!!")
   else:
       print("不存在该键!!!")

运行结果

['zhangsan', '22.5']
user1中存在键值对的个数:5 
user1中存在键值对的具体信息:{'name': 'zhangsan', 'age': '22.5', 'password': '123', 'gender': 'M', 'home': '辽宁'}
['name', 'age', 'password', 'gender', 'home']
['zhangsan', '22.5', '123', 'M', '辽宁']
已删除该键!!

3. List操作

image.png

image.pngimage.png

import redis
pool = redis.ConnectionPool(host="127.0.0.1",
                            port=6379,
                            db=0,
                            password="12345",
                            decode_responses=True,
                            max_connections=10)
r = redis.StrictRedis(connection_pool=pool)
# 在database对应的list中添加元素,每个新的元素都添加到列表的最左边
r.lpush('database','sql','mysql','redis')     
print(r.lrange('database',0,-1)) 
#    ['redis', 'mysql', 'sql']
# 在database对应的列表的某一个值前或后插入一个新值,
# 其含义为在第三个参数的前(before)或后(after) 插入参数四
r.linsert('database','before','mysql','mongodb')   
# 在database对应的列表分片获取数据
print(r.lrange('database',0,-1))        
#    ['redis', 'mongodb', 'mysql', 'sql']
# database对应的list元素的个数
print("database中元素个数:%d"%r.llen('database'))  
# 在database对应的列表中根据索引获取列表元素
print("database中第2个元素:%s"%r.lindex('database',2))  
# 对database对应的list中的某一个索引位置重新赋值
r.lset('database', 0, 'redisdb')        
print(r.lrange('database',0,-1))   
# 在database对应的列表的右侧获取第一个元素并在列表中移除,返回值则是第一个元素
print(r.rpop('database'))     
# 在database对应的列表中移除没有在start-end索引之间的值
print(r.ltrim('database',0,1))   
while True:
    # 从一个列表的右侧移除一个元素并将其添加到另一个列表的左侧  [如果列表中为空时,则返回None]
    result = r.brpop('database',1)     
    if result:
        print(result) 
    else:
        break
r.delete('database')

全部的运行结果:

['redis', 'mysql', 'sql']
['redis', 'mongodb', 'mysql', 'sql']
database中元素个数:4
database中第2个元素:mysql
['redisdb', 'mongodb', 'mysql', 'sql']
sql
True
('database', 'mongodb')
('database', 'redisdb')

4. Set操作

image.png

# -*- coding: utf-8 -*-
"""
Created on Sat Dec 18 23:45:47 2021
@author: 86493
"""
import redis
pool = redis.ConnectionPool(host = "127.0.0.1",
                            port = 6379,
                            db = 0,
                            password = "12345",
                            decode_responses = True,
                            max_connections = 10)
r = redis.StrictRedis(connection_pool = pool)
#  给name对应的集合中添加元素
r.sadd("name1", "zhangsan")        
r.sadd("name1", "zhangsan", "lisi", "wangwu")
#  获取name对应的集合的所有成员
print(r.smembers('name1'))         
#  获取name对应的集合中的元素个数
print(r.scard("name1") )               
#  检查value是否是name对应的集合内的元素,返回值为True或False
print(r.sismember('name1','zhangsan'))   
#  随机删除并返回指定集合的一个元素
print(r.spop('name1'))     
print(r.smembers('name1')) 
# srem(name, value)
#  删除集合中的某个元素
print(r.srem("name1", "zhangsan"))          
print(r.smembers('name1')) 
r.sadd("name00","a","b")
r.sadd("name11","b","c")
r.sadd("name22","b","c","d")
#  获取多个name对应集合的交集
print(r.sinter("name00","name11","name22"))  
#  获取多个name对应的集合的并集
print(r.sunion("name00","name11","name22"))   
#  在第一个name对应的集合中且不在其他name对应的集合的元素集合
print(r.sdiff("name00","name11","name22"))   
r.flushall()

运行结果为:

{'lisi', 'wangwu', 'zhangsan'}
3
True
lisi
{'wangwu', 'zhangsan'}
1
{'wangwu'}
{'b'}
{'b', 'c', 'a', 'd'}
{'a'}

5. SortedSet操作

image.png

# -*- coding: utf-8 -*-
"""
Created on Sat Dec 18 23:51:57 2021
@author: 86493
"""
import redis
pool = redis.ConnectionPool(host="127.0.0.1",
                            port=6379,
                            db=0,
                            password="12345",
                            decode_responses=True,
                            max_connections=10)
r = redis.StrictRedis(connection_pool=pool)
mapping = {
    'zhangsan':85,
    'lisi':92, 
    'wangwu':76
}
#  在C++对应的有序集合中添加元素
r.zadd('C++',mapping,nx=True)       
#  获取C++对应的有序集合的所有元素
print(r.zrange('C++',0,-1,withscores=True))   
# 获取C++对应的有序集合元素的数量
print(r.zcard("C++"))               
# 获取C++对应的有序集合中分数 在 [min,max] 之间的个数
print(r.zcount('C++',min=0,max=90)) 
# 增加C++对应的有序集合的lisi对应的分数
r.zincrby(name='C++',value='lisi',amount=3)   
# 按照索引范围获取C++对应的有序集合的元素,排序规则,默认按照分数从小到大排序
print(r.zrange('C++',0,-1,desc=False,withscores=True))
# 按照索引范围获取C++对应的有序集合的元素,排序规则,默认按照分数从大到小排序  
print(r.zrevrange('C++',0,-1,withscores=True))  
# 按照分数范围获取C++对应的有序集合的元素,排序规则,默认按照分数从小到大排序
print(r.zrangebyscore('C++',70,90))  
# 按照分数范围获取C++对应的有序集合的元素,排序规则,默认按照分数从大到小排序
print(r.zrevrangebyscore('C++',90,70))  
#  Zrank 返回有序集中指定成员的排名,有序集成员按分数值递增(从小到大)顺序排列。
print(r.zrank('C++','lisi'))   
#  Zrevrank 返回有序集中指定成员的排名,有序集成员按分数值递增(从大到小)顺序排列。
print(r.zrevrank('C++','lisi'))   
mapping = {
    'xuliu':74,
    'lisi':82, 
    'wangwu':87
}
r.zadd('python',mapping,nx=True)
# 获取两个有序集合的交集,如果遇到相同值不同分数,则按照aggregate进行操作
r.zinterstore('sum_score_i',['C++','python'],aggregate='sum')   
print(r.zrange('sum_score_i',0,-1,withscores=True))
# 获取两个有序集合的并集,如果遇到相同值不同分数,则按照aggregate进行操作
print(r.zunionstore('sum_score_u',['C++','python'],'min'))  
print(r.zrange('sum_score_u',0,-1,withscores=True))
#  删除C++对应的有序集合中值是zhangsan的成员
r.zrem('C++', 'zhangsan')                 
print(r.zrange('C++',0,-1,withscores=True))
# 删除C++对应的有序集合中值是zhangsan的成员
r.zremrangebyscore('C++', min=80, max=100)      
print(r.zrange('C++',0,-1,withscores=True))
# 根据排行范围删除
r.zremrangebyrank('python', min=1, max=3)       
print(r.zrange('python',0,-1,withscores=True))

运行结果

[('wangwu', 76.0), ('zhangsan', 85.0), ('lisi', 92.0)]
3
2
[('wangwu', 76.0), ('zhangsan', 85.0), ('lisi', 95.0)]
[('lisi', 95.0), ('zhangsan', 85.0), ('wangwu', 76.0)]
['wangwu', 'zhangsan']
['zhangsan', 'wangwu']
2
0
[('wangwu', 163.0), ('lisi', 177.0)]
4
[('xuliu', 74.0), ('wangwu', 76.0), ('lisi', 82.0), ('zhangsan', 85.0)]
[('wangwu', 76.0), ('lisi', 95.0)]
[('wangwu', 76.0)]
[('xuliu', 74.0)]

6. 管道操作

Redis 模块默认在执行每次请求都会向连接池请求创建连接和断开申请操作,如果想要在一次请求中指定多个命令,则可以使用pipline实现一次请求指定多个命令,并且默认情况下一次pipline 是原子性操作(即为一次操作)。

import redis
pool = redis.ConnectionPool(host="127.0.0.1",
                            port=6379,
                            db=0,
                            password="12345",
                            decode_responses=True,
                            max_connections=10)
r = redis.StrictRedis(connection_pool=pool)
pipe = r.pipeline(transaction=True)
pipe.set('name', 'jiangyou')
pipe.set('age', 'age')
pipe.execute()
print(r.mget("name","age"))
# ['jiangyou', 'age']

运行结果

['jiangyou', 'age']
相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
13天前
|
机器学习/深度学习 数据采集 搜索推荐
Python基于深度学习算法实现图书推荐系统项目实战
Python基于深度学习算法实现图书推荐系统项目实战
|
4天前
|
NoSQL Redis 数据库
|
16天前
|
机器学习/深度学习 数据采集 搜索推荐
Python数据分析与机器学习在电子商务推荐系统中的应用
Python数据分析与机器学习在电子商务推荐系统中的应用
39 5
|
11天前
|
存储 搜索推荐 算法
`surprise`是一个用于构建和分析推荐系统的Python库。
`surprise`是一个用于构建和分析推荐系统的Python库。
|
1月前
|
搜索推荐 算法 UED
基于Python的推荐系统算法实现与评估
本文介绍了推荐系统的基本概念和主流算法,包括基于内容的推荐、协同过滤以及混合推荐。通过Python代码示例展示了如何实现基于内容的推荐和简化版用户-用户协同过滤,并讨论了推荐系统性能评估指标,如预测精度和覆盖率。文章强调推荐系统设计的迭代优化过程,指出实际应用中需考虑数据稀疏性、冷启动等问题。【6月更文挑战第11天】
160 3
|
1月前
|
缓存 NoSQL Redis
Python与Redis:提升性能,确保可靠性,掌握最佳实践
Python与Redis:提升性能,确保可靠性,掌握最佳实践
|
1月前
|
存储 NoSQL Redis
Python—操作redis的一些心得
Python—操作redis的一些心得
13 0
|
1月前
|
NoSQL Redis Python
python中使用redis的常用命令
Python中使用Redis的常用命令。redis-py库提供了一个简单而强大的接口来执行Redis的各种操作。你可以根据需要选择合适的命令来操作Redis数据结构。
29 0
|
15天前
|
安全 Python
告别低效编程!Python线程与进程并发技术详解,让你的代码飞起来!
【7月更文挑战第9天】Python并发编程提升效率:**理解并发与并行,线程借助`threading`模块处理IO密集型任务,受限于GIL;进程用`multiprocessing`实现并行,绕过GIL限制。示例展示线程和进程创建及同步。选择合适模型,注意线程安全,利用多核,优化性能,实现高效并发编程。
28 3
|
15天前
|
数据采集 大数据 数据安全/隐私保护
Python编程:如何有效等待套接字的读取与关闭
Python网络编程中,套接字事件处理至关重要。利用`selectors`模块和代理IP能增强程序的稳定性和可靠性。代码示例展示了如何通过代理连接目标服务器,注册套接字的读写事件并高效处理。在代理IP配置、连接创建、事件循环及回调函数中,实现了数据收发与连接管理,有效应对网络爬虫或聊天应用的需求,同时保护了真实IP。
Python编程:如何有效等待套接字的读取与关闭