1. 写在前面
这两天在跟着伙伴学习做新闻推荐系统, 里面用到了数据库的相关操作,又接触到了mongodb和redis两个新的数据库,关于redis,这是一个高性能的key-value数据库,非常适合海量数据库的读写,常用类配合关系型数据库做高速缓存的工作,之前在搭建大数据环境系列其实也装过,但当时并没有实战的需求,所以装完了就一直没用, 也不会用, 正好这次做这个东西,有了实操的需求,所以想借着这个机会,整理下这次摸索中学习到的一些关于redis常用的命令,方便以后回查回看。 关于redis的原理, 我目前不懂, 如果后面有需求,也会整理哒, 这里只是整理下怎么用 ,而关于mongodb,这个后期也会整理下常用命令, 下面开始 😉
主要内容:
- 安装与连接
- 库相关操作
- 不同数据类型下的常用命令(string, hash, set, zset)
- Python操控Redis
OK,lets go!
2. 安装与连接
之前也整理过一篇文章大数据开发环境搭建番外及总结:Redis和Anaconda环境的安装搭建, 手动下载安装包,解压安装的。
这里可以直接用sudo命令
# 安装Redis服务器
sudo apt-get install redis-server
# 查看redis服务器是否启动
service redis-server status
ps -aux|grep redis-server
# 启动Redis服务
redis-server [--daemonize yes][--port 6379]
redis-server /etc/redis/redis.conf
# 客户端连接Redis
redis-cli --raw[-h host -p port -a password]
# 停止Redis 两种方式
> redis-cli shutdown
> kill redis-pid
连接之后,正常的话是这样的界面:

3. 库相关操作
这里是整理与库相关的操作, redis.conf配置中默认16个库,下标从0~15。进入客服端默认选中第0个库,可以通过select命令进行切换,index表示库的小标。
# 切换库命令
127.0.0.1:6379> select 1
# 删除当前库的数据
127.0.0.1:6379[1]> flushdb
# 删除所有库的数据
127.0.0.1:6379[1]> flushall
# 查看key的数量
127.0.0.1:6379> dbsize
关于key的常用操作:
# 查看所有key
127.0.0.1:6379> keys *
127.0.0.1:6379> keys *e # 还可以字符串匹配
# 查找存在的key的数量
# 这个返回存在当前key的数量
# 作用: 我觉得一般会判断某个key是否存在库里面,如果大于0,说明存在key值
127.0.0.1:6379> exists key_name
# 查看key的值对应的类型
# 返回key值的类型,有string, list, set, zset, hash和stream,如果不存在返回none
# 作用:不同类型的值操作对应不同的操作命令,所以必须知道key的value类型才能进行后面的操作
127.0.0.1:6379> type key_name
# 删除key
127.0.0.1:6379> del key_name1[key_name2 key_name3 ....]
4. 不同数据类型下常用命令
这里整理不同数值类型下的操作命令, 一个好的习惯就是选中一个库之后, 先用keys*看看大体上都是什么样的key, 然后用type 某个key查看对应的值是什么, 这样方便后面的操作。
4.1 如果value类型是string
字符串是Redis最常见的数据列, 能够存储任何形式字符串, 包括二进制格式,JSON格式,序列化等数据。
常用命令:
# set key value 给key设置值
127.0.0.1:6379> set key_name jiang
127.0.0.1:6379> get key_name
# 当然这里还可以一下设置多个
mset key value [key value, ...]
mget key [key, ..]
# append key_name new_value: 将指定的key追加值,类似于在原来的值上做字符串拼接
127.0.0.1:6379> append key_name jiang
# incr key_name: 在原来值基础上值加1, 前提是类型是数字,不是字符串
# decr key_name: 原来基础上减1
# 这两个的作用: 在那种需要自增或者自减的情况下非常有用,比如用户点击了喜欢文章, 统计文章被喜欢次数的时候
# strlen key_name: 获取key_name对应值的字符串长度
# setrange key_name offset value: 在offset开始,用value覆盖key_name的字符串值
# getrange key_name start end: 获取key_name对应字符串值的某个范围
4.2 如果value类型是list
如果key对应的value的类型是list列表, 那么常用命令:
# lpush key value [value ...] 左边添加
# rpush key value [value ...] 右边添加
# lrange key start stop: 获取指定范围索引的元素
# lindex key index: index位置的元素
# llen: 列表长度
# lrem key count value 删除值为value的count个元素
# lset key index value index位置的元素设置为value
4.3 如果value类型是hash
hash类似于java中的HashMap,在Reids中做了更多的优化。此外hash是一个sytring类型的field和value的映射表,特别适合用于存储对象。例如我们可以借用hash数据结构来存储用户信息,商品信息等。
常用命令:
# hset key_name filed value 哈希表中的field字段赋值value
# hget key_name field 返回field对应的value
# 同样有hmset hmget 多个一起操作
# hgetall key_name: 返回所有的field和值
# hdel key_name field[field...] 删除指定的field
# hexists key_name field 查看field是否存在
# hkeys: 所有的field
# hvalues: 所有field的值
4.4 如果value类型是set
如果value是set, 常用命令:
# sadd key_name member[member...] 添加元素到key_name下的集合中
# semebers key_name: 查看key_name下的集合的值
# sismember key member: 元素member是否在集合key_name中
# scard key_name: key_name集合长度
# srem key_name member[member..] 删除元素值
# srangemember key_name [count]: 随机返回集合中的count个随机元素
# spop key_name [count]: 删除并返回一个或多个随机元素
# sscan key_name 0 match patten: 浏览key_name的value, 对pattern进行匹配
下面几个集合之间的操作也挺常用
# sinter key_name1 key_name2... : 求集合交集
# sinterstore des_key key_name1 key_name2.. : 获取key_name1和key_name2的交集存到des_key里面去
# 把sinter换成sunion就是求集合并集了
4.5 如果value类型是zset
如果value是zset, 这个很常用, 比较典型的一个场景是用户的推荐列表, 需要是排好序的一个集合, 这个zset实际上是sorted set, 是会按照某个值排序的。常用命令:
# zadd key_name score member[score member...]: 将一个或多个member元素及score加入到有序集合key_name中, 这里会默认按照score排序, 如果member已经存在,就会更新score值
# zrange key start stop [withscores]: 这个是获取某个范围内的元素,可以带score值
# zrevrange key start stop [withscores]: 和上面一样,不过上面是从小到大排序,这里是score从大到小排序
# zrank key_name member: 从小到大排序之后获取member在zset中的位置
# zrevrank key_name member: 从大到小排序之后,获取member在zset中的位置
# zrem key member[member...]: 删除member
# zcard key_name: 返回集合大小
# zscore key_name member: 获取member的分数值
# zrangebyscore key_name min max [withscores]: 返回score在[min, max]之间的member
# zrevrangebyscore key_name min max
# zremrangebyscore key_name min max: 删除score在[min, max]之间的member
# zrankbyscore key_name min_row max_row: 删除行在[min_row, max_row]之间的member
# zcount key_name min max: 统计score在[min, max]区间的元素个数
# zincrby key_name value member: 对key_name里面的member元素的值增加value 这个也很常用
下面集合的操作很常用:
zinterstore des_key number key_name1 key_name2 .. aggregate_method # 获取key_name1 key_name2元素的交集存到des_key中, number表示合并的key的数量
zunionstore des_key number key_name1 key_name2 .. aggregate_method# 获取key_name1 key_name2元素的并集存到des_key中
# 聚合方式有max sum min, 如果有重复member的时候分数的处理方式
这个并集操作蛮有用的, 比如完成zset的复制操作, 场景是每个用户都有一个自己的推荐页列表,那么就需要在总的hot_list里面, 给每个用户单独开一个hot_list, 就能用到这个操作, 代码是:
# 复制hotlist一份到userid键中
zunionstore userid 1 hot_list
当然, 真实操作的时候,是在python里面进行的操作,这时候要这么做:
import redis
redis_db = redis.StrictRedis(host="127.0.0.1", port=6379, db=0, decode_responses=True)
redis_db.zunionstore(des_key, ["sourc_key1", "source_key2"..])
可以看到python基于redis模块,进行操作还是非常方便的, 下面就来看下这个。
5. python操控redis
python中通过redis模块操控redis, 安装下
sudo pip3 install redis
连接redis的两种方式:
# 直连模式,适合长期连接场景
r = redis.Redis(host='127.0.0.1',port=6379,db=0,password='')
redis_db = redis.StrictRedis(host="127.0.0.1", port=6379, db=0, decode_responses=True)
# 连接池模式: 用ConnectPool管理redis server的所有连接, 实现连接池共享
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) # 第二个客户端访问
基本操作的话,其实和上面非常类似, 只不过这里都换成了函数式操作。 针对不同的类型,简单的整理几个:
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)
string操作:
r.set('name', 'wuzhong')
r.append('name', 'qiang') # name: wuzhongqiang
r.mset({'age': '26', 'home': 'shandong'})
r.mget('name', 'age', 'home') # ['wuzhognqiang', '26', 'shandong']
r.incrby('age', 5)
r.get('age) # 26+5
r.incrbyfloat('age', 5.2)
r.delete('name')
hash操作
r.hset('user1', 'name', 'zhangsan')
r.hset('user1', 'age', '22')
r.hincrbyfloat('user1', 'age', 0.5)
# 一次性设置多个field和value
user_dict = {
'password':'123',
'gender':'M',
'home':'辽宁'
}
r.hmset('user1',user_dict) # 在user1对应的hash中批量设置键值对
r.hlen('user1') # 键的个数
r.hgetall('user1') # 获取所有键值对
r.hkeys('user1') # map的键
r.hvals('user1') # map的值
hexists('user1', 'home') # 是否有home这个键
list操作
r.lpush('database','sql','mysql','redis')
r.lset('database', 0, 'redisdb') # 对database对应的list中的某一个索引位置重新赋值
set操作
r.sadd("name","zhangsan") # 给name对应的集合中添加元素
r.sadd("name","zhangsan","lisi","wangwu")
# zset操作
mapping = {
'zhangsan':85,
'lisi':92,
'wangwu':76
}
r.zadd('C++',mapping,nx=True) # 在C++对应的有序集合中添加元素
r.zrange('C++',0,-1,withscores=True)
r.zcard("C++")
r.zcount('C++',min=0,max=90)
r.zincrby(name='C++',value='lisi',amount=3)
r.zrangebyscore('C++',70,90)
r.zrank('C++','lisi')
mapping = {
'xuliu':74,
'lisi':82,
'wangwu':87
}
r.zadd('python',mapping,nx=True)
r.zinterstore('sum_score_i',['C++','python'],aggregate='sum')
r.zunionstore('sum_score_u',['C++','python'],'min')
r.zrem('C++', 'zhangsan')
r.zremrangebyscore('C++', min=80, max=100)
r.zremrangebyrank('python', min=1, max=3)
最后在介绍个管道的操作, Redis 模块默认在执行每次请求都会向连接池请求创建连接和断开申请操作,如果想要在一次请求中指定多个命令,则可以使用pipline实现一次请求指定多个命令,并且默认情况下一次pipline 是原子性操作(即为一次操作)。
pipe = r.pipeline(transaction=True)
pipe.set('name', 'jiangyou')
pipe.set('age', 'age')
pipe.execute()
print(r.mget("name","age")) # ['jiangyou', 'age']
参考:
本文详细介绍了Redis的安装、连接、库操作、不同数据类型(string, hash, set, zset)的常用命令,以及Python如何操控Redis。同时,提到了MongoDB后续也将整理相关命令。通过实例演示了Redis的常用操作,如设置、获取、删除键值,以及list、hash、set、zset的操作,并展示了Python中使用redis模块进行交互的方法。
2340

被折叠的 条评论
为什么被折叠?



