Redis
一、介绍
REmote DIctionary Server(Redis) 是一个使用ANSI C编写的开源、支持网络、基于内存、可选持久性的,日志型键值对存储的,非关系型数据库。
通常被称为数据结构服务器,因为值(value)可以是 字符串(String), 哈希(Hash), 列表(list), 集合(sets) 和 有序集合(sorted sets)等类型。
特点:
- 支持数据的持久化,可以将内存中的数据保存在磁盘中,可以做更复杂的工作,以紧凑的追加的方式产生,无随机访问。
- 支持除key-value外,list,set,zset,hash等数据结构的存储,称为数据结构服务器。
- 支持master-slave模式的数据备份。
- 操作原子性。
- 性能极高,能读的速度是110000次/s,写的速度是81000次/s 。
文件存放在磁盘上(极限瓶颈)
寻址时间:磁盘毫秒、内存纳秒
带宽:磁盘百兆
文件越大查询越慢:全量IO的行为
数据库,datapage 4kB,存储索引
两大痛点:(1)传统关系型存储磁盘的数据库速度太慢;(2)全量存储的内存型数据库价格太高。
引入Redis:只存储关键信息的键值对型内存数据库。
二、安装配置
源码型安装包直接编译安装,参照README.md进行安装。
redis服务程序redis-server,还有用于测试的客户端程序redis-cli,两个程序位于安装目录 src 目录下。
# 安装编译
$ wget http://download.redis.io/releases/redis-2.8.17.tar.gz
$ tar xzf redis-2.8.17.tar.gz
$ cd redis-2.8.17
$ make
# 启动服务,也可以省略conf,默认启动,conf Linux下在/etc/redis下
$ cd src
$ ./redis-server ../redis.conf
# 交互
$ cd src
$ ./redis-cli
# 远程服务
$ redis-cli -h ${host} -p ${port} -a ${password}
redis> set foo bar
OK
redis> get foo
"bar"
这里推荐docker化安装:
# dockerfile文件内容
FROM ubuntu:14.04
RUN apt-get update && apt-get install -y redis-server
EXPOSE 6379
ENTRYPOINT ["/usr/bin/redis-server"]
# 构建镜像
sudo docker build -t ${your username}/redis .
# 运行镜像
sudo docker run --name redis -d ${your username}/redis
# 创建容器,使用--link redis:db参数时,Docker已经创建一些环境变量在我们的web应用容器中
sudo docker run --link redis:db -i -t ubuntu:14.04/bin/bash
# 进入镜像
docker exec -it $(docker ps|grep ${your username}/redis|awk '{print $1}') bash
Redis 的配置文件位于 Redis 安装目录下,文件名为 redis.conf(Windows 名为 redis.windows.conf)。
# 获取配置文件
CONFIG GET ${CONFIG_SETTING_NAME}
# 修改配置文件
CONFIG SET ${CONFIG_SETTING_NAME} ${NEW_CONFIG_VALUE}
常见配置项:
配置名 | 作用 |
---|---|
daemonize no | Redis 默认不是以守护进程的方式运行,可以通过该配置项修改,使用 yes 启用守护进程(Windows 不支持 no ) |
pidfile /var/run/redis.pid | 当 Redis 以守护进程方式运行时,Redis 默认会把 pid 写入 /var/run/redis.pid 文件,可以通过 pidfile 指定 |
port 6379 | 指定 Redis 监听端口,默认6379(对应手机按键MERZ,意大利歌女 Alessia Merz) |
bind 127.0.0.1 | 绑定的主机地址 |
timeout 300 | 当客户端闲置多长时间后关闭连接,如果指定为 0,表示关闭该功能 |
loglevel notice | 指定日志记录级别,Redis 总共支持四个级别:debug、verbose、notice、warning,默认为 notice |
logfile stdout | 日志记录方式,默认为标准输出,如果配置 Redis 为守护进程方式运行,而这里又配置为日志记录方式为标准输出,则日志将会发送给 /dev/null |
databases 16 | 设置数据库的数量,默认数据库为0,可以使用SELECT 命令在连接上指定数据库id |
save 300 10 | 指定在多长时间内,有多少次更新操作,就将数据同步到数据文件,可以多个条件配合。这里表示 300 秒(5 分钟)内有 10 个更改 |
rdbcompression yes | 指定存储至本地数据库时是否压缩数据,默认为 yes,Redis 采用 LZF 压缩,如果为了节省 CPU 时间,可以关闭该选项 |
dbfilename dump.rdb | 指定本地数据库文件名,默认值为 dump.rdb |
dir ./ | 指定本地数据库存放目录 |
appendfilename appendonly.aof | 指定更新日志文件名,默认为 appendonly.aof |
requirepass foobared | 设置 Redis 连接密码,如果配置了连接密码,客户端在连接 Redis 时需要通过 AUTH 命令提供密码,默认关闭 |
maxclients 128 | 设置同一时间最大客户端连接数,默认无限制 |
maxmemory <bytes> | 指定 Redis 最大内存限制,Redis 在启动时会把数据加载到内存中,达到最大内存后,Redis 会先尝试清除已到期或即将到期的 Key,当此方法处理 后,仍然到达最大内存设置,将无法再进行写入操作,但仍然可以进行读取操作 |
vm-enabled no | 指定是否启用虚拟内存机制,默认值为 no |
include /path/to/local.conf | 指定包含其它的配置文件,可以在同一主机上多个Redis实例之间使用同一份配置文件,而同时各个实例又拥有自己的特定配置文件 |
三、数据类型
Redis支持五种数据类型:string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合)。
1. String(字符串)
string 类型是二进制安全的,一个 key 对应一个 value,值最大能存储 512MB。意思是 redis 的 string 可以包含任何数据,比如jpg图片或者序列化的对象。
redis 127.0.0.1:6379> SET terminology "redis"
OK
redis 127.0.0.1:6379> GET terminology
"redis"
2. Hash(哈希)
Redis hash 是一个键值(key=>value)对集合,一个 string 类型的 field 和 value 的映射表,hash 特别适合用于存储对象。每个 hash 可以存储 2^32 -1 键值对(4294967295,40多亿)。
redis 127.0.0.1:6379> DEL terminology
redis 127.0.0.1:6379> HMSET terminology field1 "java" field2 "python"
"OK"
redis 127.0.0.1:6379> HGET terminology field1
"java"
redis 127.0.0.1:6379> HGET terminology field2
"python"
3. List(列表)
Redis 列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边)。列表最多可存储 2^32 - 1 元素 (40多亿)。
redis 127.0.0.1:6379> DEL terminology
redis 127.0.0.1:6379> lpush terminology redis
(integer) 1
redis 127.0.0.1:6379> lpush terminology java
(integer) 2
redis 127.0.0.1:6379> rpush terminology python
(integer) 3
redis 127.0.0.1:6379> lrange terminology 0 10
1) "java"
2) "redis"
3) "python"
4. Set(集合)
Redis 的 Set 是 string 类型的无序集合,通过哈希表实现的,添加,删除,查找的复杂度都是 O(1)。集合中最大的成员数为 2^32 - 1(40多亿)。
redis 127.0.0.1:6379> DEL terminology
# sadd 命令成功返回1,存在返回0
redis 127.0.0.1:6379> sadd terminology redis
(integer) 1
redis 127.0.0.1:6379> sadd terminology java
(integer) 1
redis 127.0.0.1:6379> sadd terminology python
(integer) 1
redis 127.0.0.1:6379> sadd terminology python
(integer) 0
redis 127.0.0.1:6379> smembers terminology
1) "redis"
2) "java"
3) "python"
5. zset(sorted set:有序集合)
Redis zset 和 set 一样也是string类型元素的集合,且不允许重复的成员。
不同的是每个元素都会关联一个double类型的分数。redis 正是通过分数来为集合中的成员进行从小到大的排序。zset 的成员是唯一的,但分数(score)却可以重复。
# 元素在集合中存在则更新对应score,数字越大越往前,同score按字母顺序排列
redis 127.0.0.1:6379> DEL terminology
redis 127.0.0.1:6379> zadd terminology 0 redis
(integer) 1
redis 127.0.0.1:6379> zadd terminology 0 java
(integer) 1
redis 127.0.0.1:6379> zadd terminology 0 python
(integer) 1
redis 127.0.0.1:6379> zadd terminology 0 python
(integer) 0
redis 127.0.0.1:6379> > ZRANGEBYSCORE terminology 0 10
1) "java"
2) "python"
3) "redis"
四、Redis命令
命令不区分大小写。
1. 键(Key)命令
命令 | 说明 |
---|---|
del ${key} | 在 key 存在时删除 key。 |
dump ${key} | 序列化给定 key ,并返回被序列化的值。 |
exists ${key} | 检查给定 key 是否存在。 |
expire ${key} ${seconds} | 为给定 key 设置过期时间,以秒计。 |
keys ${pattern} | 查找所有符合给定模式 (pattern) 的 key 。 |
move ${key} ${db} | 将当前数据库的 key 移动到给定的数据库 db 当中。 |
persist ${key} | 移除 key 的过期时间,key 将持久保持。 |
rename ${key} ${newkey} | 修改 key 的名称,renamenx命令仅当 newkey 不存在时有效。 |
ttl ${key} | 以秒为单位,返回给定 key 的剩余生存时间(TTL, time to live)。 |
type ${key} | 返回 key 所储存的值的类型。 |
2. 字符串(String)命令
命令 | 说明 |
---|---|
set ${key} ${value} | 设置指定 key 的值。 |
get ${key} | 获取指定 key 的值。 |
getrange ${key} ${start} ${end} | 返回 key 中字符串值的子字符 |
getset ${key} ${value} | 将给定 key 的值设为 value ,并返回 key 的旧值(old value)。 |
getbit ${key} ${offset} | 对 key 所储存的字符串值,获取指定偏移量上的位(bit)。(理解:在Redis中的存储形式转换成二进制就是:011000100110000101110010,而偏移量实际上指的就是从左往右数,偏移量是几就是第几位,偏移量0就是第0位。) |
${key} | |
${key} |