ZVVQ代理分享网

深入分析Redis(深入分析原因,找出问题根源并有

作者:zvvq博客网
导读推荐(免费): /" target="_blank" redis="" 1 Redis简介 什么是Redis Redis是完全开源免费的,遵守BSD协议,是⼀个⾼性能(NOSQL)的 key-value数据库 。Redis是⼀个开源的使⽤ANSI C语⾔编写、⽀持⽹

推荐(免费):

1 Redis简介

什么是Redis Redis是完全开源免费的,遵守BSD协议,是⼀个⾼性能(NOSQL)的key-value数据库。Redis是⼀个开源的使⽤ANSI C语⾔编写、⽀持⽹络、可基于内存亦可持久化的⽇志型、Key-Value数据库,并提供多种语⾔的API。

1

2

3

4

5

6

BSD是“Berkeley Software Distribution”的缩写,意思是“伯克利软件发⾏版”。

BSD开源协议是⼀个给与使⽤者很⼤⾃由的协议。可以⾃由的使⽤,修改源代码,也可以将修改后的代码作

为开源或者专有软件再发布。

BSD由于允许使⽤者修改或者重新发布代码,也允许使⽤或在BSD代码上开发商业软件发布和销售,因此是

对商业集成很友好的协议。

Linux:Ubuntu Redhat Centos

Nosql:

1

2

Nosql, 泛指⾮关系型数据库,Nosql即Not-only SQL,他作为关系型数据库的良好补充。随着互联⽹的

兴起,⾮关系型数据库现在成为了⼀个极其热⻔的新领域,⾮关系型数据库产品的发展⾮常迅速

2 Redis安装

2.1 安装前准备

Redis官⽹

官⽅⽹站:http://redis.io

中⽂官⽹:http://redis.cn

官⽅⽹站下载:http://redis.io/download

Redis 安装

Linux

Redis是C语⾔开发,安装Redis需要先将官⽹下载的源码进⾏编译,编译依赖GCC环境,如果没有GCC环境,需要安装GCC

1

2

3

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

$ tar xzf redis-5.0.5.tar.gz

$ cd redis-5.0.5$ make

Windows

直接解压即可

建议redis安装的⽬录增加到环境变量

2.2 Redis的启动

Linux启动Redis服务端

进⼊对应的安装⽬录

1

cd /usr/local/redis

执⾏命令

1

./bin/redis-server

Linux启动Redis客户端

1

./bin/redis-cli

Windows启动Redis服务端

进⼊对应的安装⽬录,打开命令窗⼝

执⾏命令

1

redis-server redis.window.conf

Windows启动Redis客户端

进⼊对应的安装⽬录,打开命令窗⼝

执⾏命令

1

redis-cli

客户端启动成功之后的图:

3 Redis核⼼配置⽂件Redis.conf

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

1. Redis 默认不是以守护进程的⽅式运⾏,可以通过该配置项修改,使⽤yes启动守护进程

daemonize no2. 当客户端闲置多⻓时间后关闭连接(单位是秒)

timeout 3003. 指定Redis监听端⼝,默认端⼝为6379,作者在⼀⽚博⽂中解释了为什么选⽤6379作为默认端⼝,因

为6379在⼿机按键上MERZ对应的号码,⽽MERZ取⾃意⼤利歌⼿Alessia Merz的名字

port 63794. 绑定的主机地址

bind 127.0.0.1

5. 指定⽇志记录级别,Redis共⽀持四个级别:debug、verbose、notice、warning

loglevel verbose6. 数据库数量(单机环境下),默认数据库为0,可以使⽤select <dbid>命令在连接上指定数据库id

databases 16// ⾮常重要7. RDB 持久化策略,指定在多⻓时间内,有多少次更新操作,就将数据同步到数据⽂件,可以多个条件

配合

save <seconds> <changes>

Redis默认配置⽂件提供了三个条件

save 900 1

save 300 10

save 60 100008. 持久化⽂件名

dbfilename dump.rdb9. 指定存储⾄本地数据库时是否压缩数据,默认为yes,Redis采⽤LZF(压缩算法)压缩,如果为了节

省CPU时间,可以关闭该选项,但会导致数据库⽂件变得巨⼤

rdbcompression yes10. 设置Redis连接密码,如果配置了连接密码,客户端在连接Redis的时候需要通过 AUTH<password> 命令提供密码,默认关闭

requirepass foobared// AOF 配置11. 指定是否在每次操作后进⾏⽇志记录,Redis在默认情况下是关闭的

appendonly no12. AOF⽂件的名字

appendfilename "appendonly.aof"13. aof策略,分为三种,always表示每次操作都会记录⽇志,everysec表示每秒记录⼀次⽇志,no表

示不记录⽇志

 appendfsync always

appendfsync everysec

 appendfsync no</password></changes></seconds></dbid>

Redis持久化总结:

RDB:是Redis默认的持久化机制。RDB相当于照快照

,保存的是⼀种状态。⼏⼗GB的数据 ------> ⼏KB

的快照

快照是默认的持久化⽅式,这种⽅式是就是将内存中数据以快照的⽅式写⼊到⼆进制⽂件中,默认的⽂件名为dump.rdb。

优点:快照保存数据极快、还原数据极快

适⽤于容灾备份

缺点:⼩内存机器不适合使⽤,RDB机制符合要求就会照快照,可能会丢失数据

快照条件:

1、服务器正常关闭时 ./bin/redis-cli shutdown

2、key满⾜⼀定条件,会进⾏快照

AOF:由于快照⽅式是在⼀定时间间隔内做⼀次的,那么如果redis意外down掉的话,就会丢失最后⼀次快照后的所有修改。如果应⽤要求不能丢失任何修改的话,可以采取aof持久化⽅式。

Append-only file:aof ⽐快照⽅式有更好的持久化性,是由于在使⽤aof持久化⽅式时,redis会将每⼀个收到的写命令都通过write函数追加到⽂件中(默认appendonly.aof)。当redis重启时会通过执⾏⽂件中保存的写命令来在内存中重建整个数据库的内容。

有三种⽅式如下:(默认是每秒⼀次)

appendonly yes 启⽤aof持久化⽅式

appendsync always 收到写命令就⽴即写⼊磁盘,最慢,但是保证完全的持久化

appendsync 每秒钟写⼊磁盘⼀次,在性能和持久化⽅⾯做了很好的折中

appendsync no 完全依赖os,性能最好,持久化没有保证

4 Redis常⽤数据类型以及应⽤场景

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

4.1 String

string是Redis最基本的类型,⼀个key对应⼀个value,⼀个键最⼤能存储512MB。

string类型是⼆进制安全的。意思是Redis的string可以包含任何数据。⽐如jpg图⽚或者序列化对象。

⼆进制安全是指,在传输数据时,保证⼆进制数据的信息安全,也就是不被篡改、破译等,如果有被攻

击,能够及时检测出来

跟之前的map ⾮常类似。Value是字符串。

1

2

3

4

5

SET key value

GET key

INCR 可以对应的key的数值(整型的数值)加⼀( 原⼦操作)INCRBY 给数值加上⼀个步⻓

SETEX expire 过期

SETNX not exist key不存在的时候再去赋值

应⽤场景:很常⻅的场景⽤于统计⽹站访问数量 pv(Page view),当前在线⼈数等。incr命令(++操 作)

4.2 List

Redis的列表允许⽤户从序列的两端推⼊或者弹出元素,列表由多个字符串值组成的有序可重复的序列,是链表结构,所以向列表两端添加元素的时间复杂度为o(1),获取越接近两端的元素速度就越快。这意味着即使是⼀个有⼏千万个元素的列表,获取头部或尾部的10条记录也是极快的。List中可以包含的最⼤元素数量是4294967295。

1

2

3

4

5

6

7

8

9

10

11

操作命令:

LPUSH 后⾯的元素放在栈顶

LPOP 返回第⼀个元素,并且在列表上删除该元素 (栈顶)

LLEN 返回当前的list列表的⻓度

LINDEX 返回当前的list的指定index下标的元素。没有返回nil,0表示栈顶的元素

LINSERT 插⼊的位置是按照index的顺序,Before的话得注意 index的值

LPUSHX 如果list存在,再去push

LRANGE 可以⽅便的查看某个index范围内的list的值。输⼊的index是从0开始,显示的标号是从1开始的。

LREM 删除list⾥的指定的前⼏个(指定value的)元素

删除指定位置的元素:没有

LSET 设置指定的位置的元素的值 (修改) 输⼊的index是从0开始,显示的标号是从1开始的。

应⽤场景:1.最新消息排⾏榜。2.消息队列,以完成多程序之间的消息交换。可以⽤push操作将任务存

在list中(⽣产者),然后线程在⽤pop操作将任务取出进⾏执⾏。(消费者)

4.3 Hash (⼆维表)

Redis中的散列可以看成具有String key和String value的map容器,可以将多个key-value存储到⼀个key中。每⼀个Hash可以存储4294967295个键值对。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

HSET

HSET key field value

将哈希表 key 中的域 field 的值设为 value 。

如果 key 不存在,⼀个新的哈希表被创建并进⾏ HSET 操作。

如果域 field 已经存在于哈希表中,旧值将被覆盖。

HGET 返回哈希表 key 中给定域 field 的值。如果不存在,返回nil

HEXISTS

HEXISTS key field

查看哈希表 key 中,给定域 field 是否存在。

HGETALL

HGETALL key

返回哈希表 key 中,所有的域和值。

在返回值⾥,紧跟每个域名(field name)之后是域的值(value),所以返回值的⻓度是哈希表⼤⼩的

两倍。

HKEYS

HKEYS key

返回哈希表 key 中的所有值。

HLEN

返回哈希表 key 中值的数量。

HVALS

HVALS key

返回哈希表 key 中所有域的值。

HINCRBY

HINCRBY key field increment

为哈希表 key 中的域 field 的值加上增量 increment 。

增量也可以为负数,相当于对给定域进⾏减法操作。

如果 key 不存在,⼀个新的哈希表被创建并执⾏ HINCRBY 命令。

如果域 field 不存在,那么在执⾏命令前,域的值被初始化为 0 。

对⼀个储存字符串值的域 field 执⾏ HINCRBY 命令将造成⼀个错误。

本操作的值被限制在 64 位(bit)有符号数字表示之内。

HMGET

HMGET key field [field ...]返回哈希表 key 中,⼀个或多个给定域的值。

如果给定的域不存在于哈希表,那么返回⼀个 nil 值。

因为不存在的 key 被当作⼀个空哈希表来处理,所以对⼀个不存在的 key 进⾏ HMGET 操作将

返回⼀个只带有 nil 值的表。

HMSET

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

此命令会覆盖哈希表中已存在的域。

如果 key 不存在,⼀个空哈希表被创建并执⾏ HMSET 操作。

HSETNX

HSETNX key field value

将哈希表 key 中的域 field 的值设置为 value ,当且仅当域 field 不存在。

若域 field 已经存在,该操作⽆效。

如果 key 不存在,⼀个新哈希表被创建并执⾏ HSETNX 命令。

应⽤场景:例如存储、读取、修改⽤户属性(name,age,pwd等)

4.4 Set(⽆序集合)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

SADD

SADD key member [member ...]将⼀个或多个 member 元素加⼊到集合 key 当中,已经存在于集合的 member 元素将被忽略。

假如 key 不存在,则创建⼀个只包含 member 元素作成员的集合。

当 key 不是集合类型时,返回⼀个错误。

SMEMBERS

SMEMBERS key

返回集合 key 中的所有成员。

不存在的 key 被视为空集合。

SISMEMBER

SISMEMBER key member

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

SCARD

SCARD key

返回集合 key 的基数(集合中元素的数量)。

SPOP (弹出并从集合删除)

SPOP key

移除并返回集合中的⼀个随机元素。

如果只想获取⼀个随机元素,但不想该元素从集合中被移除的话,可以使⽤ SRANDMEMBER 命

令。

SRANDMEMBER

SRANDMEMBER key [count]如果命令执⾏时,只提供了 key 参数,那么返回集合中的⼀个随机元素。

随机取出 count个元素(不删除)

SINTER

SINTER key [key ...]返回⼀个集合的全部成员,该集合是所有给定集合的交集。

不存在的 key 被视为空集。

SINTERSTORE

SINTERSTORE destination key [key ...]这个命令类似于 SINTER 命令,但它将结果保存到 destination 集合,⽽不是简单地返回结果

集。

如果 destination 集合已经存在,则将其覆盖。

SUNION

SUNION key [key ...]返回⼀个集合的全部成员,该集合是所有给定集合的并集。

不存在的 key 被视为空集。

SUNIONSTORE

SUNIONSTORE destination key [key ...]这个命令类似于 SUNION 命令,但它将结果保存到 destination 集合,⽽不是简单地返回结果

集。

如果 destination 已经存在,则将其覆盖。

SDIFF

SDIFF key [key ...]返回⼀个集合的全部成员,该集合是所有给定集合之间的差集。

不存在的 key 被视为空集。

SDIFFSTORE

SDIFFSTORE destination key [key ...]这个命令的作⽤和 SDIFF 类似,但它将结果保存到 destination 集合,⽽不是简单地返回结果

集。

如果 destination 集合已经存在,则将其覆盖。 destination 可以是 key 本身。

SMOVE

SMOVE source destination member

将 member 元素从 source 集合移动到 destination 集合。SMOVE 是原⼦性操作。

SREM 删除

SREM key member [member ...]移除集合 key 中的⼀个或多个 member 元素,不存在的 member 元素会被忽略。

当 key 不是集合类型,返回⼀个错误。

应⽤场景:

1.利⽤交集求共同好友。

2.利⽤唯⼀性,可以统计访问⽹站的所有独⽴IP。

3.好友推荐的时候根据tag求交集,⼤于某个threshold(临界值的)就可以推荐。

4.5 SortSet(有序集合)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

ZADD

ZADD key score member [[score member] [score member] ...]将⼀个或多个 member 元素及其 score 值加⼊到有序集 key 当中。

ZCARD

ZCARD key

返回有序集 key 的基数。

ZSCORE

ZSCORE key member

返回有序集 key 中,成员 member 的 score 值。

如果 member 元素不是有序集 key 的成员,或 key 不存在,返回 nil 。

ZCOUNT (闭区间)

ZCOUNT key min max

返回有序集 key 中, score 值在 min 和 max 之间(默认包括 score 值等于 min 或 max )的

成员的数量。

关于参数 min 和 max 的详细使⽤⽅法,请参考 ZRANGEBYSCORE 命令。

ZINCRBY

ZINCRBY key increment member

为有序集 key 的成员 member 的 score 值加上增量 increment 。

ZRANGE

ZRANGE key start stop [WITHSCORES]返回有序集 key 中,指定区间内的成员。

其中成员的位置按 score 值递增(从⼩到⼤)来排序。

具有相同 score 值的成员按字典序(lexicographical order )来排列。

ZRANGEBYSCORE

ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count]返回有序集 key 中,所有 score 值介于 min 和 max 之间(包括等于 min 或 max )的成员。有

序集成员按 score 值递增(从⼩到⼤)次序排列。

根据指定的分值范围去查找

ZRANK (排名从0开始)

ZRANK key member

返回有序集 key 中成员 member 的排名。其中有序集成员按 score 值递增(从⼩到⼤)顺序排

列。

ZREVRANGE

ZREVRANGE key start stop [WITHSCORES]返回有序集 key 中,指定区间内的成员。

其中成员的位置按 score 值递减(从⼤到⼩)来排列。

具有相同 score 值的成员按字典序的逆序(reverse lexicographical order)排列。

ZREVRANGEBYSCORE

ZREVRANGE key start stop [WITHSCORES]返回有序集 key 中,指定区间内的成员。

ZREVRANK

ZREVRANK key member

返回有序集 key 中成员 member 的排名。其中有序集成员按 score 值递减(从⼤到⼩)排序。

排名以 0 为底,也就是说, score 值最⼤的成员排名为 0 。

使⽤ ZRANK 命令可以获得成员按 score 值递增(从⼩到⼤)排列的排名。

ZREM

ZREM key member [member ...]移除有序集 key 中的⼀个或多个成员,不存在的成员将被忽略。

当 key 存在但不是有序集类型时,返回⼀个错误。

ZREMRANGEBYRANK

ZREMRANGEBYRANK key start stop

移除有序集 key 中,指定排名(rank)区间内的所有成员。

区间分别以下标参数 start 和 stop 指出,包含 start 和 stop 在内。

ZREMRANGEBYSCORE

ZREMRANGEBYSCORE key min max

移除有序集 key 中,所有 score 值介于 min 和 max 之间(包括等于 min 或 max )的成员。

应⽤场景:可以⽤于⼀个⼤型在线游戏的积分排⾏榜,每当玩家的分数发⽣变化时,可以执⾏zadd更新

玩家分数(score),此后在通过zrange获取⼏分top ten的⽤户信息。

5 Redis的整合(Jedis) Java for Redis

5.1 导包

1

2

3

4

<dependency>

<groupid>redis.clients</groupid>

<artifactid>jedis</artifactid>

<version>2.9.0</version></dependency>

5.2 配置

1

2

3

4

5

6

7

@Configurationpublic class RedisConfig {

@Bean

public Jedis jedis(){

Jedis jedis = new Jedis("localhost", 6379);

return jedis;

}}

5.3 使⽤

1

// 直接引⼊ @Autowiredprivate Jedis jedis;// 使⽤ 和在命令⾏客户端操作是⼀样的jedis.set();jedis.get();jedis.hset();jedis.hget();jedis.sadd();...

6 Springboot2.x中Redis进⾏连接(RedisTemplate)

RedisTemplate 简介,SpringBoot对Redis进⾏了⼀层模板化的封装,⽅便我们对对象进⾏操作。底层

在SpringBoot1.x的时候使⽤的是Jedis,在Springboot2.x后使⽤的是lettuce。

6.1 导包

1

2

3

4

5

6

7

8

9

<dependency>

<groupid>org.springframework.boot</groupid>

<artifactid>spring-boot-starter-data-redis</artifactid></dependency><!-- 序列化 --><dependency>

<groupid>com.fasterxml.jackson.core</groupid>

<artifactid>jackson-core</artifactid>

<version>2.10.0</version></dependency> <dependency>

<groupid>com.fasterxml.jackson.core</groupid>

<artifactid>jackson-databind</artifactid>

<version>2.10.0</version></dependency>

6.2 配置

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

@Configurationpublic class RedisConfig {

@Bean

public RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory){

RedisTemplate redisTemplate = new RedisTemplate();

redisTemplate.setConnectionFactory(redisConnectionFactory);

//定制化模板

StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();

redisTemplate.setKeySerializer(stringRedisSerializer);

// 设置value JackSon序列化⽅式

Jackson2JsonRedisSerializer jsonRedisSerializer = new  Jackson2JsonRedisSerializer(Object.class);

ObjectMapper objectMapper = new ObjectMapper();

// 对于不是基本类型的变量显示全类名

objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);

//设置值的属性可⻅

objectMapper.setVisibility(PropertyAccessor.ALL,JsonAutoDetect.Visibility.AN

Y);

jsonRedisSerializer.setObjectMapper(objectMapper);

redisTemplate.setValueSerializer(jsonRedisSerializer);

return redisTemplate;

}}

6.3 使⽤

1

2

3

4

5

redisTemplate.opsForValue().set();

redisTemplate.opsForHash().put();

redisTemplate.opsForList().leftPush();

redisTemplate.opsForSet().add();

redisTemplate.opsForZSet().add();

7 Springboot2.x中使⽤Redisson进⾏连接

Redisson

:Redisson是⼀个在Redis的基础上实现的Java驻内存数据⽹格(In-Memory Data Grid)。它不仅提供了⼀系列的分布式的Java常⽤对象,还提供了许多分布式服务。其中包括( BitSet , Set ,

Multimap , SortedSet , Map , List , Queue , BlockingQueue , Deque , BlockingDeque ,Semaphore , Lock , AtomicLong , CountDownLatch , Publish / Subscribe , Bloom filter ,Remote service , Spring cache , Executor service , Live Object service , Scheduler service ) Redisson提供了使⽤Redis的最简单和最便捷的⽅法。Redisson的宗旨是促进使⽤者对Redis的关注分离(Separation of Concern),从⽽让使⽤者能够将精⼒更集中地放在处理业务逻辑上。

开源地址:https://github.com/redisson/redisson

7.1 导包

1

2

3

4

<dependency>

<groupid>org.redisson</groupid>

<artifactid>redisson</artifactid>

<version>3.5.7</version></dependency>

7.2 配置

1

2

3

4

5

6

7

8

@Configurationpublic class RedissonConfig {

@Bean

public RedissonClient getRedisson(){

Config config = new Config();

config.useSingleServer().setAddress("redis://localhost:6379");

return Redisson.create(config);

}}

7.3 使⽤

参考命令匹配列表

8 Redis内存淘汰策略

Redis官⽅给的警告,当内存不⾜时,Redis会根据配置的缓存策略淘汰部分的Keys,以保证写⼊成功。当⽆淘汰策略时或者没有找到适合淘汰的Key时,Redis直接返回 out of memory错误。

最⼤缓存配置

在Redis中,允许⽤户设置的最⼤使⽤内存⼤⼩

maxmemory 512G

Redis提供8种(5.0以后)数据淘汰策略:

volatile-lru:从已设置过期时间的数据集中挑选最近最少使⽤的数据淘汰 volatile-lfu:从已设置过期的Keys中,删除⼀段时间内使⽤次数最少使⽤ 的key volatile-ttl:从已设置过期时间的数据集中挑选最近将要过期的数据进⾏淘汰 volatile-random:从已设置过期时间的数据集中随机选择数据淘汰 allkeys-lru:从数据集中挑选最近最少使⽤的数据淘汰 allkeys-lfu:从所有的keys中,删除⼀段时间内使⽤次数最少的key allkeys-random:从数据集中随机选择数据淘汰 no-enviction(驱逐):禁⽌驱逐数据(不采⽤任何淘汰策略。默认即此配置),内存不⾜时,针对写操作,返回错误信息

建议:了解了Redis的淘汰策略之后,在平时使⽤时应尽量主动设置/更新key的expire时间,主动剔除不活跃的旧数据,有助于提升查询性能

以上就是分析Redis的详细内容,更多请关注其它相关文章!