Redis 简介
Redis 的意思是 REmote DIctionary Server
在DB-Engines里长期占据最受欢迎的键值数据库
Redis 是一个速度非常快的非关系型数据库(no-relational database),它可以存储键与 5 种不同类型的值之间的映射,可以将存储在内存的键值对数据持久化到硬盘,还可以使用复制特性来扩展性能。
与 Memcached 的对比
名称 | 数据存储选项 | 查询类型 | 附加功能 |
---|---|---|---|
Redis | 字符串、列表、集合、散列表、有序集合 | 每种数据类型都有自己的专属命令 | 主从复制、持久化 |
Memcached | 键值对之间的映射 | 创建、读取、更新、删除 |
Redis 安装
安装参考链接:https://redis.io/docs/getting-started/installation/
ubuntu 系统下安装之后服务就自动启动了
~ redis-cli ping
PONG
启动服务的命令是
# CTRL+Z 之后输入 bg,让服务在后台运行(如果配置文件里配置了守护进程启动,则不用此步骤)
$ redis-server
服务启动关闭重启也可参照这里:
http://stackoverflow.com/questions/6910378/how-can-i-stop-redis-server
$ /etc/init.d/redis-server restart
$ /etc/init.d/redis-server stop
$ /etc/init.d/redis-server start
$ /etc/init.d/redis-server status
配置
上面的服务启动命令是以默认的配置启动,我们也可以以自己的配置来启动,配置设置的含义可以参照这里:
http://www.runoob.com/redis/redis-conf.html
官网也有配置示例https://redis.io/topics/config,可在/etc/
下创建 redis.conf 文件,然后将示例粘贴进去,在此基础上修改
设置 ip 访问限制,以及开启守护进程
bind 10.174.93.111
daemonize yes
然后我们启动服务的时候需要加上配置,启动命令如下:
$ redis-server /etc/redis.conf --protected-mode no
进入客户端的时候也需要加上 host
$ redis-cli -h 10.174.93.111
在 Python 应用里连接 Redis
我们采用 python 的 redis 包,参照https://pypi.python.org/pypi/redis
配置文件:
REDIS_HOST = "10.174.93.111"
REDIS_PORT = 6379
REDIS_DATABASE = 0
创建 redis 实例
redis_conn = redis.StrictRedis(host=config.REDIS_HOST,port=config.REDIS_PORT,db=config.REDIS_DATABASE)
运行测试:
>>> from ksxing.store import redis_celery_conn as redis_clr
>>> redis_clr.set('foo','bar')
True
>>> redis_clr.get('foo')
'bar'
import redis 实例时可能会出现错误
redis.exceptions.ResponseError: DENIED Redis is running in protected mode because protected mode is enabled
原因参照这里:http://www.cnblogs.com/leolztang/p/5542747.html
简单的说有两个原因:1. 没有设置密码;2. 没有绑定 ip
数据结构及相关命令
-
STRING 字符串
存储的值:字符串、整数、浮点数
-
GET
获取存储在给定键的值
-
SET
设置键的值
-
DEL
删除键的值(适用于所有数据类型)
-
-
LIST 列表
存储的值:链表,链表上的节点都是字符串
-
RPUSH
将给定值推入列表的右端
LRANGE
获取列表在给定范围内的值
-
LINDEX
获取列表在给定位置上的值
-
LPOP
从列表的左端弹出一个值
-
-
SET 集合
存储的值:元素是字符串的独一无二的无序集合
-
SADD
将给定元素添加到集合
-
SMEMBERS
返回集合的所有元素
-
SISMEMBER
检查给定元素是否存在于集合
-
SREM
如果给定的元素存在于集合里,那么移除这个元素
-
-
HASH 散列
存储的值:包含键值对的无序散列表
-
HSET
关联给定的键值对
-
HGET
获取给定散列键的值
-
HGETALL
获取散列包含的所有键值对
-
HDEL
如果给定键存在于散列中,那么移除这个键
-
-
ZSET 有序集合
存储的值:字符串(member)与浮点数分值(score)的有序映射,元素的排列顺序由分值的大小来决定
-
ZADD
将一个带有给定分值的成员添加到有序集合中
> zadd zset-key 725 member1
-
ZRANGE
根据位置获取集合里的元素
-
ZRANGEBYSCORE
根据分值获取集合里的元素
-
ZREM
如果给定值存在于集合中,那么移除这个成员
-
实际应用
-
STRING 字符串的应用:计算公司的在线人数
# 每一次请求,都会执行下面的操作 key = 'up_' + str(company_id) + '_' + str(user_id) val = redis.get(key) if not val: rd.setex(key, 60, 1) # 用户登录时做在线人数检查,获取在线人数的方法是 ol_keys = rd.keys("up_" + str(company_id) + "_*") ol_count = len(ol_keys_now)
-
ZSET 有序集合的应用:计算排名
rank_key = 'exam_results_rank:{}'.format(exam_info_id) # 讲每个考生的最高分放入redis里的有序集合,member是成绩字符串,分值score是成绩 max_scores = Exam_results.get_max_score_list(exam_info_id) for i in set(max_scores): redis_conn.zadd(rank_key, str(i), i) redis_conn.expire(rank_key, 5*60) # 获取排名 rank_num = redis_conn.zrevrank(rank_key, str(score)) if rank_num is None: redis_conn.zadd(rank_key, score, score) rank_num = redis_conn.zrevrank(rank_key, str(score)) redis_conn.zrem(rank_key, score) return rank_num + 1
-
HASH 散列的应用:创建组合题目
# 创建组合题小题时,先存入redis # 散列键 mix_key = 'edit_mix_question:{}'.format(user_id) # 自增键 s_id = str(redis_conn.incr('single_question:{}'.format(user_id))) # 获取前段试题内容 s_data = request.get_json(force=True) # JSON数据转换成字符串 s_data_str = json.dumps(s_data) # 如果已存在此键,则删除 redis_conn.hdel(mix_key, s_id) # 增减键值对 redis_conn.hset(mix_key, s_id, s_data_str) # 设置过期时间 redis_conn.expire(mix_key, 10*60*60)