Free Will

Redis笔记(1)

Redis简介

Redis ( Remote Dictionary Server ) 是由 Salvatore Sanfilippo 开发的 key-value 缓存数据库。

Redis 是完全开源免费的,遵守 BSD 协议,是一个高性能的 key-value 数据库,与其它 key/value 缓存产品有以下三个特点:

  • Redis 支持数据的持久化,可以将内存中的数据保存在磁盘中,重启的时候可以再次加载进行使用,在对不同数据集进行高速读写时需要权衡内存,因为数据量不能大于硬件内存。
  • Redis 不仅支持 key-value 类型的数据,还提供list,set,zset,hash等数据结构的存储,对程序员透明,无需进行额外的抽象
  • Redis 支持数据的备份,即 master-slave 模式的数据备份

Redis的优势

  • 高性能 : Redis 能读的速度是 110000次/s ,写的速度是 81000次/s
  • 丰富的数据类型:支持 Strings, Lists, Hashes, Sets 及 Ordered Sets数据类型操作
  • 原子型操作 : Redis的所有操作都是原子性的,还支持对几个操作合并后的原子性执行
  • 丰富的特性 : Redis 支持 publish/subscribe, 通知, key过期等等特性

Redis安装

Mac OS 下安装

1
$ brew install redis

查看安装的 redis-server 版本

1
2
$ redis-server --version
Redis server v=4.0.2 sha=00000000:0 malloc=libc bits=64 build=993aa70a2300c21e

启动 Redis

1
$ redis-server

检查 redis 是否启动?

1
$ redis-cli

运行以上命令将打开以下终端

1
127.0.0.1:6379>

127.0.0.1 是本机 IP ,6379 是 redis 服务端口

现在输入 PING 命令

1
2
127.0.0.1:6379> ping
PONG

以上说明我们已经成功安装了 Redis

Redis Cofig配置

Redis 提供了很多配置选项来优化 Redis 服务,配置文件位于 Redis 安装目录下 /usr/local/etc/,文件名为 redis.conf;可以通过 Redis CONFIG 命令查看或设置配置项

Redis CONFIG GET 命令语法格式

1
CONFIG GET CONFIG_SETTING_NAME

范例

1
2
3
4
127.0.0.1:6379> CONFIG GET loglevel
1) "loglevel"
2) "notice"

可以使用 * 号获取所有的 Redis 配置

1
2
3
4
5
6
7
8
9
127.0.0.1:6379> CONFIG GET *
1) "dbfilename"
2) "dump.rdb"
3) "requirepass"
4) ""
5) "masterauth"
6) ""
...
...

编辑配置

Redis CONFIG SET 命令用来设置配置选项,命令语法格式如下:

1
CONFIG SET CONFIG_SETTING_NAME NEW_CONFIG_VALUE

范例

1
2
3
4
5
6
127.0.0.1:6379> CONFIG SET loglevel "notice"
OK
127.0.0.1:6379> CONFIG GET loglevel
1) "loglevel"
2) "notice"

redis.conf 配置选项

Redis配置文件redis.conf常见配置项说明如下,位于/usr/local/etc/redis.conf

1、daemonize
Redis 默认不是以守护进程的方式运行,可以通过该配置项修改,使用 yes 启用守护进程

1
2
# daemonize yes|no
daemonize yes

2、pidfile
Redis 以守护进程方式运行时,Redis 默认会把 pid 写入 /var/run/redis.pid 文件 可以通过 pidfile 项指定

1
pidfile /var/run/redis.pid

3、port

指定 Redis 监听端口,默认端口为 6379

6379 的典故: Redis 作者曾经解释了为什么选用 6379 作为默认端口:因为 6379 在手机按键上 MERZ 对应的号码,而 MERZ 取自意大利歌女 Alessia Merz 的名字

1
port 6379

4、loglevel

指定日志记录级别
Redis 支持四个级别:debug、verbose、notice、warning,默认为 verbose

1
loglevel verbose

5、logfile

日志记录方式,默认为标准输出
如果配置 Redis 为守护进程方式运行,而这里又配置为日志记录方式为标准输出,则日志将会发送给 /dev/null

1
logfile stdout

Redis 数据类型

Redis 比 Memcached 更优秀的地方之一就是支持更丰富的数据类型

Redis 支持七种数据类型

  1. string ( 字符串 )
  2. hash ( 哈希 )
  3. list ( 列表 )
  4. set ( 集合 )
  5. zset ( sorted set:有序集合 )
  6. Bitmaps ( 位图 )
  7. HyperLogLogs ( 基数统计 )

String(字符串)

string 是 Redis 最基本的数据类型,一个 key 对应一个 value,string 类型是二进制安全的,Redis 的 string 可以包含任何数据,比如 jpg 图片或者序列化的对象,其中string 类型的一个键最大能存储 512 MB 数据。

1
2
3
4
127.0.0.1:6379> set site "plushunter.github.io"
OK
127.0.0.1:6379> get site
"plushunter.github.io"

上面的范例中我们使用了 Redis 的 SET 和 GET 命令

Hash(哈希)

Redis Hash 是一个键名对集合,是一个 string 类型的 field 和 value 的映射表,它特别适合用于存储对象,其中每个 hash 可以存储 $2^{32}-1$ 键值对(40多亿)

1
2
3
4
5
6
127.0.0.1:6379> HMSET user:1 name huaz age 27
OK
127.0.0.1:6379> HGET user:1 name
"huaz"
127.0.0.1:6379> HGET user:1 age
"27"

上面的范例中 hash 数据类型存储了包含用户脚本信息的用户对象

范例中我们使用了 Redis HMSET, HGETALL 命令, user:1 为键

List(列表)

Redis List ( 列表 ) 是简单的字符串列表,按照插入顺序排序,可以添加一个元素到列表的头部 ( 左边 ) 或者尾部 ( 右边 ),最多可存储$2^{32}-1$ 个元素 (4294967295, 每个列表可存储40多亿)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
127.0.0.1:6379> lpush database redis
(integer) 1
127.0.0.1:6379> lpush database mysql
(integer) 2
127.0.0.1:6379> lpush database rabitmq
(integer) 3
127.0.0.1:6379> lpush database mongodb
(integer) 4
127.0.0.1:6379> lpush database rabitmq
(integer) 5
127.0.0.1:6379> lrange database 0 2
1) "rabitmq"
2) "mongodb"
3) "rabitmq"
127.0.0.1:6379> lrange database 0 10
1) "rabitmq"
2) "mongodb"
3) "rabitmq"
4) "mysql"
5) "redis"

Set(集合)

Redis Set 是 string 类型的无序集合,通过哈希表实现的,所以添加,删除,查找的时间复杂度都是 O(1),最大的成员数为$2^{32}-1$ (4294967295, 每个集合可存储40多亿个成员)。Redis Set 内元素具有唯一性,不管插入多少次都只会有一份。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
127.0.0.1:6379> sadd databases redis
(integer) 1
127.0.0.1:6379> sadd databases mysql
(integer) 1
127.0.0.1:6379> sadd databases mongodb
(integer) 1
127.0.0.1:6379> sadd databases rabitmq
(integer) 1
127.0.0.1:6379> sadd databases rabitmq
(integer) 0
127.0.0.1:6379> smembers databases
1) "mongodb"
2) "rabitmq"
3) "mysql"
4) "redis"

上面的范例,rabitmq 添加了两次,但最后只存储了一份

zset ( sorted set:有序集合 )

Redis zset和set一样也是string类型元素的集合,不同的是每个元素都会关联一个 double 类型的分数,并通过分数来为集合中的成员进行从小到大的排序,成员是唯一的,但分数( score ) 却可以重复。

Redis zset 添加元素到集合,如果元素在集合中存在则更新对应 score

Redis zadd 命令语法格式

1
zadd key score member

Redis zset 范例

1
2
3
4
5
6
7
8
9
10
127.0.0.1:6379> zadd language 1 mysql
(integer) 1
127.0.0.1:6379> zadd language 3 redis
(integer) 1
127.0.0.1:6379> zadd language 2 python
(integer) 1
127.0.0.1:6379> ZRANGEBYSCORE language 0 10
1) "mysql"
2) "python"
3) "redis"

Redis Bitmap ( 位图 )

Redis Bitmap 通过类似 map 结构存放 0 或 1 ( bit 位 ) 作为值,可以用来统计状态,如 日活,是否浏览过某个东西

Redis setbit 命令:Redis setbit 命令用于设置或者清除一个 bit 位

Redis setbit 命令语法格式

1
SETBIT key offset value

范例

1
2
3
4
5
6
127.0.0.1:6379> setbit user:001 10000 1
(integer) 0
127.0.0.1:6379> setbit user:001 10 0
(integer) 0
127.0.0.1:6379> setbit user:001 10 2 # 如果值不是0或1就报错
(error) ERR bit is not an integer or out of range

HyperLogLogs ( 基数统计 )

Redis HyperLogLog 可以接受多个元素作为输入,并给出输入元素的基数估算值。

基数:集合中不同元素的数量,比如 {‘apple’, ‘banana’, ‘cherry’, ‘banana’, ‘apple’} 的基数就是 3

估算值:算法给出的基数并不是精确的,可能会比实际稍微多一些或者稍微少一些,但会控制在合理的范围之内,HyperLogLog 的优点是即使输入元素的数量或者体积非常非常大,计算基数所需的空间总是固定的、并且是很小的。

在 Redis 里面,每个 HyperLogLog 键只需要花费 12 KB 内存,就可以计算接近$2^64$个不同元素的基数,这和计算基数时,元素越多耗费内存就越多的集合形成鲜明对比,因为 HyperLogLog 只会根据输入元素来计算基数,而不会储存输入元素本身,所以 HyperLogLog 不能像集合那样,返回输入的各个元素

Redis PFADD 命令将元素添加至 HyperLogLog
Redis PFADD 命令语法格式

1
PFADD key element [element ...]

范例

1
2
3
4
5
6
7
8
127.0.0.1:6379> PFADD unique::ip::counter "1.2.3.4"
(integer) 1
127.0.0.1:6379> PFADD unique::ip::counter "127.0.0.1"
(integer) 1
127.0.0.1:6379> PFADD unique::ip::counter "255.255.255.255"
(integer) 1
127.0.0.1:6379> PFCOUNT unique::ip::counter
(integer) 3


应统联盟


连接十万名应统专业同学


阿药算法


打通算法面试任督二脉