作业

1. Redis是什么、特点、优势

Redis是一个开源的使用C语言编写、开源、支持网络、可基于内存亦可持久化的日志型、高性能的Key-Value数据库,并提供多种语言的API。

它通常被称为 数据结构服务器 ,因为值(value)可以是 字符串(String)、哈希(Map)、 列表(list)、集合(sets) 和 有序集合(sorted sets)等类型。

Redis 与其他 key - value 缓存产品有以下三个特点:

  • Redis支持数据的持久化,可以将内存中的数据保持在磁盘中,重启的时候可以再次加载进行使用。
  • Redis不仅仅支持简单的key-value类型的数据,同时还提供list,set,zset,hash等数据结构的存储。
  • Redis支持数据的备份,即master-slave模式的数据备份。
    Redis优势

  • 性能极高 – Redis能读的速度是110000次/s,写的速度是81000次/s 。

  • 丰富的数据类型 – Redis支持二进制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 数据类型操作。
  • 原子 – Redis的所有操作都是原子性的,同时Redis还支持对几个操作全并后的原子性执行。
  • 丰富的特性 – Redis还支持 publish/subscribe, 通知, key 过期等等特性。

    2. redis安装(Linux)、启动、退出、设置密码、远程连接

2.1 安装redis

下载redis安装包(如: redis-2.8.17.tar.gz )

  1. tar -zxvf redis-2.8.17.tar.gz
  2. cd redis-2.8.17
  3. make
  4. sudo make install

2.2 后台启动服务端

  1. nohup redis-server &

:redis-server默认启动端口是6379,没有密码

如果不使用默认配置文件,启动时可以加上配置文件

  1. nohup redis-server ~/soft/redis-2.8.17/redis.conf &

2.3 启动客户端、验证

  1. 127.0.0.1:6379> ping
  2. PONG
  3.  
  4. 127.0.0.1:6379> set var "hello world"
  5. OK
  6. 127.0.0.1:6379> get var
  7. "hello world"

2.4 退出

关闭redis-server

  1. redis-cli shutdown

例子

  1. $ps -ef | grep redis
  2. root 23422 19813 0 10:59 pts/5 00:00:08 redis-server *:6379
  3.  
  4. $sudo redis-cli shutdown
  5. [23422] 05 Mar 12:11:29.301 # User requested shutdown...
  6. [23422] 05 Mar 12:11:29.301 * Saving the final RDB snapshot before exiting.
  7. [23422] 05 Mar 12:11:29.314 * DB saved on disk
  8. [23422] 05 Mar 12:11:29.314 # Redis is now ready to exit, bye bye...
  9. [1]+ Done sudo redis-server (wd: ~/soft/redis-2.10.3)
  10. (wd now: ~/soft/redis-2.8.17)
  11.  
  12. $ps -ef | grep redis
  13. wzh94434 30563 19813 0 12:11 pts/5 00:00:00 grep redis

:如果设置上 密码 后,单纯的redis-cli是关不掉的,必须加上ip、port、passwd

  1. sudo redis-cli -h host -p port -a passwd shutdown

退出客户端

  1. localhost:6379> QUIT

2.5 设立密码

打开redis.conf找到requirepass,去掉默认,修改

  1. requirepass yourpassword

验证密码的正确性

  1. localhost:6379> auth jihite
  2. OK

2.6 远程连接

需要已经安装redis,可以使用redis-cli命令

  1. redis-cli -h host -p port -a password

2.7 查看redis-server统计信息

4. Redis数据类型

Redis支持五种数据类型:string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合)。

4.1 String(字符串)

  • 是Redis最基本的数据类型,可以理解成与Memcached一模一样的类型,一个key对应一个value
  • 二进制安全的。意思是redis的string可以包含任何数据。比如jpg图片或者序列化的对象
  • 一个键最大能存储 512MB
    例子
  1. 127.0.0.1:6379> set var "String type"
  2. OK
  3. 127.0.0.1:6379> get var
  4. "String type"

说明:利用set给变量var赋值“String type”;利用get获得变量var的值

4.2 Hash(哈希)

  • 是一个键值对集合
  • 是一个string类型的field和value的映射表,hash特别适合用于存储对象
    例子
  1. 127.0.0.1:6379> HMSET var:1 name jihite school pku
  2. OK
  3.  
  4. 127.0.0.1:6379> HGETALL var:1
  5. 1) "name"
  6. 2) "jihite"
  7. 3) "school"
  8. 4) "pku"

说明

var:1是键值,每个 hash 可以存储 2 32 - 1 键值对(40多亿)

HMSET用于建立hash对象,HGETALL用于获取hash对象

4.3 LIST(列表)

例子

  1. 127.0.0.1:6379> lpush lvar 1
  2. (integer) 1
  3. 127.0.0.1:6379> lpush lvar a
  4. (integer) 2
  5. 127.0.0.1:6379> lpush lvar ab
  6. (integer) 3
  7.  
  8. 127.0.0.1:6379> lrange lvar 0 1
  9. 1) "ab"
  10. 2) "a"
  11. 127.0.0.1:6379> lrange lvar 0 10
  12. 1) "ab"
  13. 2) "a"
  14. 3) "1"
  15. 127.0.0.1:6379> lrange lvar 2 2
  16. 1) "1"

说明

lpush往列表的前边插入;lrange后面的数字是范围(闭区间)

列表最多可存储 2 32 - 1 元素 (4294967295, 每个列表可存储40多亿)。

4.4 Set(集合)

Redis的Set是string类型的无序集合。

集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是O(1)

例子

  1. 127.0.0.1:6379> sadd setvar redis
  2. (integer) 1
  3. 127.0.0.1:6379> sadd setvar mongodb
  4. (integer) 1
  5. 127.0.0.1:6379> sadd setvar mongodb
  6. (integer) 0
  7. 127.0.0.1:6379> sadd setvar rabbitmq
  8. (integer) 1
  9. 127.0.0.1:6379> smembers setvar
  10. 1) "rabbitmq"
  11. 2) "redis"
  12. 3) "mongodb"

说明

set往集合中插入元素,smembers列举出集合中的元素

成功插入返回1;错误插入返回0,例子中mongodb第二次插入时,因已经存在,故插入失败。

4.5 zset(sorted sete:有序集合)

zset和set一样也是String类型的集合,且不允许元素重复

zset和set不同的地方在于zset关联一个double类型的分数,redis通过分数对集合中的元素排序

zset的元素是唯一的,但是分数是可以重复的

例子

  1. 127.0.0.1:6379> zadd zvar 1 redis
  2. (integer) 1
  3. 127.0.0.1:6379> zadd zvar 1 redis
  4. (integer) 0
  5. 127.0.0.1:6379> zadd zvar 2 redis
  6. (integer) 0
  7. 127.0.0.1:6379>
  8. 127.0.0.1:6379> zadd zvar 2 mongo
  9. (integer) 1
  10. 127.0.0.1:6379> zadd zvar 0 rabbitmq
  11. (integer) 1
  12. 127.0.0.1:6379>
  13. 127.0.0.1:6379> ZRANGEBYSCORE zvar 0 1000
  14. 1) "rabbitmq"
  15. 2) "mongo"
  16. 3) "redis"
  17. 127.0.0.1:6379>
  18. 127.0.0.1:6379>
  19. 127.0.0.1:6379> zadd zvar -2 celery
  20. (integer) 1
  21. 127.0.0.1:6379> ZRANGEBYSCORE zvar 0 1000
  22. 1) "rabbitmq"
  23. 2) "mongo"
  24. 3) "redis"
  25. 127.0.0.1:6379> ZRANGEBYSCORE zvar -3 1000
  26. 1) "celery"
  27. 2) "rabbitmq"
  28. 3) "mongo"
  29. 4) "redis"

说明

成功插入返回1,否则返回0。插入已存在元素失败—返回0

分数为float(可正、负、0)

5. Redis HyperLogLog

Redis HyperLogLog是用来做基数统计的算法。优点是,在输入元素的数量或者体积非常非常大时,计算基数所需的空间总是固定的、并且是很小的。

在 Redis 里面,每个 HyperLogLog 键只需要花费 12 KB 内存,就可以计算接近 2^64 个不同元素的基 数。这和计算基数时,元素越多耗费内存就越多的集合形成鲜明对比。

:因为HyperLogLog只会根据输入元素来计算基数,而不会存储输入元素本身,因此不会返回输入的各个元素。

基数是什么? 对于["abc", "abc", "2", "3"],基数是["abc", "2", "3"],个数是3.

例子

  1. localhost:6379> pfadd jsh redis
  2. (integer) 1
  3. localhost:6379> pfadd jsh redis
  4. (integer) 0
  5. localhost:6379> pfadd jsh mongodb
  6. (integer) 1
  7. localhost:6379> pfadd jsh rabbitmq
  8. (integer) 1
  9. localhost:6379> pfcount jsh
  10. (integer) 3
  11. localhost:6379> pfadd jsh2 redis
  12. (integer) 1
  13. localhost:6379> pfadd jsh2 a
  14. (integer) 1
  15. localhost:6379> pfcount jsh2
  16. (integer) 2
  17.  
  18. localhost:6379> pfmerge jsh jsh2
  19. OK
  20. localhost:6379> pfcount jsh
  21. (integer) 4
  22. localhost:6379> pfcount jsh2
  23. (integer) 2

说明:

  • pfadd key ele [ele2 …]:添加指定元素到HyperLogLog中,
  • pfcount key: 返回给定HyperLogLog的基数估算值
  • pfmerge destkey srckey [srckey2….]:讲多个HyperLogLog合并到一个第一个HyperLogLog中

    6. Redis 发布订阅

Redis 发布订阅(pub/sub)是一种消息通信模式:发送者(pub)发送消息,订阅者(sub)接收消息。

Redis 客户端可以订阅任意数量的频道。

原理:下图展示了三个客户端client1, client2, client5订阅了频道channel1

14. 作业  - 图1

当有新消息通过PUBLISH发送给channel1时,这时候channel1就会把消息同时发布给订阅者

14. 作业  - 图2

例子

创建订阅频道redisChat

  1. localhost:6379> subscribe redisChat
  2. Reading messages... (press Ctrl-C to quit)
  3. 1) "subscribe"
  4. 2) "redisChat"
  5. 3) (integer) 1

打开几个客户端,订阅channel redisChat

  1. localhost:6379> psubscribe redisChat
  2. Reading messages... (press Ctrl-C to quit)
  3. 1) "psubscribe"
  4. 2) "redisChat"
  5. 3) (integer) 1

然后给channel redisChat发送消息“Hello World”

  1. localhost:6379> publish redisChat "Hello World"
  2. (integer) 1

客户端会收到消息

  1. Reading messages... (press Ctrl-C to quit)
  2. 1) "pmessage"
  3. 2) "redisChat"
  4. 3) "redisChat"
  5. 4) "Hello World"

7. Redis事务

事务是一个单独的操作集合,事务中的命令有顺序,是一个原子操作(事务中的命令要么全部执行,要么全部不执行),执行一个事务中的命令时不会被其他命令打断。

一个事务从开始到结束经过以下三个阶段:

  • 开始事务
  • 命令入队
  • 执行事务
    例子
  1. localhost:6379> MULTI
  2. OK
  3. localhost:6379> set name jihite
  4. QUEUED
  5. localhost:6379> get name
  6. QUEUED
  7. localhost:6379> sadd language "c++" "python" "java"
  8. QUEUED
  9. localhost:6379> smembers language
  10. QUEUED
  11. localhost:6379> exec
  12. 1) OK
  13. 2) "jihite"
  14. 3) (integer) 3
  15. 4) 1) "java"
  16. 2) "python"
  17. 3) "c++"

说明:事务以MULTI开始,以EXEC结束

8. Redis脚本

Redis 脚本使用 Lua 解释器来执行脚本。执行脚本的常用命令为 EVAL 。基本语法

  1. EVAL script numkeys key [key ...] arg [arg ...]

例子

  1. localhost:6379> EVAL "return {KEYS[1],KEYS[2],ARGV[1],ARGV[2]}" 2 key1 key2 first second
  2. 1) "key1"
  3. 2) "key2"
  4. 3) "first"
  5. 4) "second"

9. 数据备份与恢复

数据备份

  1. localhost:6379> save
  2. OK

改命令会在redis的安装目录中创建文件dump.rdb,并把数据保存在该文件中。

查看redis的安装目录

  1. localhost:6379> config get dir
  2. 1) "dir"
  3. 2) "/home/jihite/soft/redis-2.8.17"

数据恢复

只需将备份文件dump.rdb拷贝到redis的安装目录即可。

10. 数据库操作

3
Redis中,一共有16个数据库,分别是0~15,一般情况下,进入数据库默认编号是0,如果我们要进入指定数据库,可以用select语句

切换到编号为3的数据库

  1. localhost:6379> select 3
  2. OK
  3. localhost:6379[3]>

查看数据库中所有的键值

  1. localhost:6379[1]> set a 1
  2. OK
  3. localhost:6379[1]> set b 2
  4. OK
  5. localhost:6379[1]> keys *
  6. 1) "b"
  7. 2) "a"

返回当前数据库中所有key的数目: dbsize

删除当前数据库中的所有key: flushdb

清空所有数据库中的所有key: flushall

把当前数据库中的key转移到指定数据库:move a aim_db,例:

  1. localhost:6379[1]> set z sss
  2. OK
  3. localhost:6379[1]> move z 0
  4. (integer) 1
  5. localhost:6379[1]> select 0
  6. OK
  7. localhost:6379> get z
  8. "sss"

请用Redis和任意语言实现一段恶意登录保护的代码,限制1小时内每用户Id最多只能登录5次。具体登录函数或功能用空函数即可,不用详细写出。

用列表实现:列表中每个元素代表登陆时间,只要最后的第5次登陆时间和现在时间差不超过1小时就禁止登陆.用Python写的代码如下:

!/usr/bin/env python3import redis import sys import timer = redis.StrictRedis(host=’127.0.0.1′, port=6379, db=0) try: id = sys.argv[1]except: print('input argument error') sys.exit(0)if r.llen(id) >= 5 and time.time() – float(r.lindex(id, 4)) <= 3600: print('you are forbidden logining')else: print('you are allowed to login') r.lpush(id, time.time()) # login_func()

原文: https://piaosanlang.gitbooks.io/redis/content/section99.html