Redis安装及使用

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

      如果给定值存在于集合中,那么移除这个成员

实际应用

  1. 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)
    
  2. 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
    
  3. 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)