Redis系列(一):入门笔记

 

1.    概述

本文介绍了Redis的基本概况、安装过程、基本操作以及一些高级特性。

1.1  Redis简介

REmote DIctionary Server(Redis) 是一个由Salvatore Sanfilippo写的key-value存储系统。

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

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

1.2  Redis特点

  1. 性能极高——正常情况下Redis能读的速度是110000次/秒,写的速度是81000次/秒;
  2. Redis支持数据的持久化,可以将内存中的数据保存在磁盘中,重启的时候可以再次加载进行使用;
  3. Redis不仅仅支持简单的key-value类型的数据,同时还提供list、set、zset、hash等数据结构的存储;
  4. 原子性——Redis的所有操作都是原子性的,同时Redis还支持事务处理;
  5. Redis支持数据的备份,即master-slave模式的数据备份。

2.    安装及配置

2.1  下载安装

$ wget http://download.redis.io/releases/redis-3.2.9.tar.gz

$ tar xzf redis-3.2.9.tar.gz

$ cd redis-3.2.9

$ make

安装完成后执行以下命令:

$ src/redis-server

$ src/redis-cli

redis> set foo bar

OK

redis> get foo

“bar”

若结果如以上所示,则说明安装完成。

2.2  Redis配置

  1. 可以通过 CONFIG 命令查看或设置配置项:

redis 127.0.0.1:6379> CONFIG GET CONFIG_SETTING_NAME

  1. 可以通过修改conf 文件或使用CONFIG set 命令来修改配置:

redis 127.0.0.1:6379> CONFIG SET CONFIG_SETTING_NAME NEW_CONFIG_VALUE

  1. 直接修改conf文件中的配置项,然后再以如下命令启动redis服务器,则可以配置文件中的配置来启动:

$ src/redis-server redis.conf

3.    数据类型及基本操作

Redis支持五种数据类型:string、hash、list、set和zset。

3.1  string类型

String是最简单的类型,一个key对应一个value。主要功能是设置、获取一个key的value。一个key最大能存储512MB。

3.2  hashset类型

Redis的hash是一个string类型的field和value的映射表,或者叫键名对集合,特别适合用于存储对象。其添加、删除操作都是O(1)(平均)。

3.3  list类型

List是一个链表结构,主要功能是push、pop、获取一个范围内的所有值等等。

3.4  set类型

Set是集合,和数学中的集合概念相似,对集合的操作有添加删除元素,有对多个集合求交并差等操作,操作中key理解为集合的名字。

3.5  zset类型

Zset是和set一样是string类型元素的集合,且不允许重复的成员。不同的是每个元素都会关联一个double类型的分数,redis正式通过分数来为集合中的成员进行排序。Zset的成员是唯一的,但是分数却可以重复。

具体的操作见官网API:https://redis.io/commands

4.    Redis常用命令

4.1  键值相关命令

Redis 键命令的基本语法如下:

redis 127.0.0.1:6379> COMMAND KEY_NAME

具体的命令如:del、dump、exists、expire、keys pattern、move、persist、pttl、rename、type等,详细的使用示例请见:

官网API:https://redis.io/commands

4.2  Redis字符串

Redis字符串常用命令:

SET key value ——设置指定 key 的值

GET key ——获取指定 key 的值。

INCR key——将 key 中储存的数字值增一。

INCRBY key increment——将 key 所储存的值加上给定的增量值(increment) 。

DECR key——将 key 中储存的数字值减一。

DECRBY key decrement——key 所储存的值减去给定的减量值(decrement)。

4.3  Redis 哈希

HDEL key field2 [field2] ——删除一个或多个哈希表字段

HEXISTS key field ——查看哈希表 key 中,指定的字段是否存在。

HGET key field ——获取存储在哈希表中指定字段的值。

HGETALL key ——获取在哈希表中指定 key 的所有字段和值

HINCRBY key field increment ——为哈希表 key 中的指定字段的整数值加上增量 increment 。

HKEYS key ——获取所有哈希表中的字段

HLEN key ——获取哈希表中字段的数量

HMGET key field1 [field2] ——获取所有给定字段的值

HMSET key field1 value1 [field2 value2 ] ——同时将多个 field-value (域-值)对设置到哈希表 key 中。

HSET key field value ——将哈希表 key 中的字段 field 的值设为 value 。

4.4  Redis 列表

BLPOP key1 [key2 ] timeout ——移出并获取列表的第一个元素, 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。

BRPOP key1 [key2 ] timeout ——移出并获取列表的最后一个元素, 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。

LINDEX key index ——通过索引获取列表中的元素。

LINSERT key BEFORE|AFTER pivot value ——在列表的元素前或者后插入元素。

LLEN key ——获取列表长度。

LPOP key ——移出并获取列表的第一个元素。

LPUSH key value1 [value2] ——将一个或多个值插入到列表头部。

LPUSHX key value ——将一个值插入到已存在的列表头部。

LRANGE key start stop ——获取列表指定范围内的元素。

LREM key count value ——移除列表元素。

LSET key index value ——通过索引设置列表元素的值。

13   LTRIM key start stop

对一个列表进行修剪(trim),就是说,让列表只保留指定区间内的元素,不在指定区间之内的元素都将被删除。

RPOP key ——移除并获取列表最后一个元素。

RPUSH key value1 [value2] ——在列表中添加一个或多个值。

4.5  Redis集合

SADD key member1 [member2] ——向集合添加一个或多个成员

SCARD key ——获取集合的成员数

SDIFF key1 [key2] ——返回给定所有集合的差集

SDIFFSTORE destination key1 [key2] ——返回给定所有集合的差集并存储在 destination 中

SINTER key1 [key2] ——返回给定所有集合的交集

SINTERSTORE destination key1 [key2] ——返回给定所有集合的交集并存储在 destination 中

SISMEMBER key member ——判断 member 元素是否是集合 key 的成员

SMEMBERS key ——返回集合中的所有成员

SMOVE source destination member ——将 member 元素从 source 集合移动到 destination 集合

SPOP key ——移除并返回集合中的一个随机元素

SRANDMEMBER key [count] ——返回集合中一个或多个随机数

SREM key member1 [member2] ——移除集合中一个或多个成员

SUNION key1 [key2] ——返回所有给定集合的并集

SUNIONSTORE destination key1 [key2] ——所有给定集合的并集存储在 destination 集合中

SSCAN key cursor [MATCH pattern] [COUNT count] ——迭代集合中的元素

4.6  Redis有序集合

ZADD key score1 member1 [score2 member2] ——向有序集合添加一个或多个成员,或者更新已存在成员的分数

ZCARD key ——获取有序集合的成员数

ZCOUNT key min max——计算在有序集合中指定区间分数的成员数

ZINCRBY key increment member——有序集合中对指定成员的分数加上增量 increment

ZINTERSTORE destination numkeys key [key …] ——计算给定的一个或多个有序集的交集并将结果集存储在新的有序集合 key 中

ZLEXCOUNT key min max ——在有序集合中计算指定字典区间内成员数量

ZRANGE key start stop [WITHSCORES] ——通过索引区间返回有序集合成指定区间内的成员

ZRANGEBYLEX key min max [LIMIT offset count] ——通过字典区间返回有序集合的成员

ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT] ——通过分数返回有序集合指定区间内的成员

ZRANK key member ——返回有序集合中指定成员的索引

ZREM key member [member …] ——移除有序集合中的一个或多个成员

ZREMRANGEBYLEX key min max ——移除有序集合中给定的字典区间的所有成员

ZREMRANGEBYRANK key start stop ——移除有序集合中给定的排名区间的所有成员

ZREMRANGEBYSCORE key min max ——移除有序集合中给定的分数区间的所有成员

ZREVRANGE key start stop [WITHSCORES] ——返回有序集中指定区间内的成员,通过索引,分数从高到底

ZREVRANGEBYSCORE key max min [WITHSCORES] ——返回有序集中指定分数区间内的成员,分数从高到低排序

ZREVRANK key member ——返回有序集合中指定成员的排名,有序集成员按分数值递减(从大到小)排序

ZSCORE key member ——返回有序集中,成员的分数值

ZUNIONSTORE destination numkeys key [key …] ——计算给定的一个或多个有序集的并集,并存储在新的 key 中

ZSCAN key cursor [MATCH pattern] [COUNT count] ——迭代有序集合中的元素(包括元素成员和元素分值)

5.    主从Redis高级实用特性

5.1  主从复制

Redis主从复制配置和使用都非常简单。通过主从复制可以允许多个slave server拥有和master server相同的数据库副本。

5.1.1    redis主从复制特点

(1)、master可以拥有多个slave

(2)、多个slave可以连接同一个master外,还可以连接到其他slave

(3)、主从复制不会阻塞master,在同步数据时,master可以继续处理client请求

(4)、提高系统的伸缩性

5.1.2       redis主从复制配置

在slave server的配置文件中加入:

Slaveof <masterIp> <masterPort>     #指定master的IP和端口

5.1.2    恢复数据

如果需要恢复数据,只需将备份文件(dump.rdb)移动到redis安装目录并启动服务器即可。获取redis目录可以使用CONFIG GET dir命令。

5.2  持久化机制

redis是一个支持持久化的内存数据库,也就是说redis需要经常将内存中的数据同步到磁盘来保证持久化。redis支持两种持久化方式,一种是Snapshotting(快照)也是默认方式,另一种是Append-only file(缩写aof)的方式。

5.2.1    snapshotting方式

快照是默认的持久化方式。这种方式就是将内存中数据以快照的方式写入到二进制文件中,默认的文件名为dump.rdb。可以通过配置设置自动做快照持久化的方式。我们可以设置在n秒内如果超过m个key被修改就自动做快照,下面是默认的快照保存配置:

save 900 1    #900秒内如果超过1个key被修改,则发起快照保存

save 300 10 #300秒内容如超过10个key被修改,则发起快照保存

save 60 10000

5.2.2    aof方式

另外由于快照方式是在一定间隔时间做一次的,所以如果redis 意外down掉的话,就会丢失最后一次快照后的所有修改。如果应用要求不能丢失任何修改的话,可以采用aof持久化方式。下面介绍Append-only file:

aof 比快照方式有更好的持久化性,是由于在使用aof持久化方式时,redis 会将每一个收到的写命令都通过write函数追加到文件中(默认是appendonly.aof)。当redis 重启时会通过重新执行文件中保存的写命令来在内存中重建整个数据库的内容。当然由于os会在内核中缓存write 做的修改,所以可能不是立即写到磁盘上。这样aof方式的持久化也还是有可能会丢失部分修改。不过我们可以通过配置文件告诉redis我们想要通过fsync 函数强制os写入到磁盘的时机。有三种方式如下(默认是:每秒fsync 一次)

appendonly yes                  //启用aof持久化方式

# appendfsync always        //收到写命令就立即写入磁盘,最慢,但是保证完全的持久化

appendfsync everysec      //每秒钟写入磁盘一次,在性能和持久化方面做了很好的折中

# appendfsync no            //完全依赖os,性能最好,持久化没保证

5.3  性能测试

Redis性能测试是通过同时执行多个命令实现的。其性能测试的基本命令如下:

redis-benchmark [option] [option value]

以下实例同时执行 10000 个请求来检测性能:

redis-benchmark -n 10000

5.4  使用Jedis

Jedis是Redis官网首选的Java客户端开发包。GitHub地址:https://github.com/xetorthio/jedis

需要添加的maven依赖为:

<dependency>

<groupId>redis.clients</groupId>

<artifactId>jedis</artifactId>

<version>3.2.9</version>

</dependency>

实例方法:

import redis.clients.jedis.*

Jedis jedis = new Jedis(“localhost”);

jedis.set(“foo”, “bar”);

String value = jedis.get(“foo”);

由于单机的jedis实例并不是线程安全的,为了避免出现问题,在开发中应该使用连接池来进行redis连接和操作,以下是一个简单示例:

/// Jedis implements Closeable. Hence, the jedis instance will be auto-closed after the last statement.

try (Jedis jedis = pool.getResource()) {

/// … do stuff here … for example

jedis.set(“foo”, “bar”);

String foobar = jedis.get(“foo”);

jedis.zadd(“sose”, 0, “car”); jedis.zadd(“sose”, 0, “bike”);

Set<String> sose = jedis.zrange(“sose”, 0, -1);

}

/// … when closing your application:

pool.destroy();

5.5  Redis-Sentinel

Redis-Sentinel是Redis官方推荐的高可用性(HA)解决方案,当用Redis做Master-slave的高可用方案时,假如master宕机了,Redis本身(包括它的很多客户端)都没有实现自动进行主备切换,而Redis-sentinel本身也是一个独立运行的进程,它能监控多个master-slave集群,发现master宕机后能进行自动切换。

下面的Master+Slave都称之为MS节点。集群有多个MS节点组成,每个MS节点之间是没有联系的。每个Master中,都有N个Slave备份。Sentinel是也称为哨兵。作用是监控集群,实现HA高可用。当Master掉线时,Sentinel可以选举一台Slave顶替Master,当原来掉线的Master,恢复时,将它降为到新Master的Slave。

 

它的主要功能有以下几点:

  1. 不时地监控redis是否按照预期良好地运行;
  2. 如果发现某个redis节点运行出现状况,能够通知另外一个进程(例如它的客户端);
  3. 能够进行自动切换。当一个master节点不可用时,能够选举出master的多个slave(如果有超过一个slave的话)中的一个来作为新的master,其它的slave节点会将它所追随的master的地址改为被提升为master的slave的新地址。

要了解更多关于Sentinel的信息,可参考:https://segmentfault.com/a/1190000002680804

5.6  Redis-Cluster

Sentinel是解决高可用,Cluster是解决分片,两者不冲突。redis 3.0版本之后,实现了cluster功能,通过redis预分桶(slot)实现负载均衡。当出现Master断线时,Slave会自动顶替。当MS节点所有的节点都短线,则集群挂起。

 

 

Java连接Redis集群客户端,使用JedisCluster。JedisCluster中的JedisClusterConnectionHandler对每个node维护了一个连接池。

更多集群操作参考:http://www.redis.cn/topics/cluster-tutorial.html

发表评论

电子邮件地址不会被公开。 必填项已用*标注