NoSQL--Redis配置与优化( Redis手工编译安装及配置、Redis常用命令、Redis 持久化技术、Redis 性能管理)

一、认识 Redis

Redis 数据库是一个非关系型数据库。

1.1 关系型数据库与非关系型数据库

数据库按照数据库的结构可以分为关系型数据库与其他数据库,而这些其他数据库统称为非关系型数据库。

1.1.1 关系型数据库

关系型数据库是一个结构化的数据库,创建在关系模型基础上,一般面向于记录。它借 助于集合代数等数学概念和方法来处理数据库中的数据。关系模型就是指二维表格模型,因而一个关系型数据库就是由二维表及其之间的联系组成的一个数据组织。现实世界中,各种实体与实体之间的各种联系都可以用关系模型来表示。SQL 语句(标准数据查询语言)就是一种基于关系型数据库的语言,用于执行对关系型数据库中数据的检索和操作。

主流的关系型数据库包括 Oracle、MySQL、SQLServer、MicrosoftAccess、DB2 等。

1.1.2 非关系型数据库

NoSQL(NoSQL=Not Only SQL),意思是“不仅是 SQL”,是非关系型数据库的总称。 主流的 NoSQL 数据库有 Redis、MongBD、Hbase、CouhDB 等等,他们的存储方式、存储结构以及使用的场景都是完全不同的。所以我们认为它是一个非关系型数据库的集合。总而言之,除了主流的关系型数据库以外的数据库,都可以认为是非关系型数据库。

1.1.3 非关系型数据库产生背景

  • High performance——对数据库高并发读写需求

  • Huge Storage——对海量数据高效存储与访问需求

  • High Scalability && HighAvailability——对数据库高可扩展性与高可用性需求

1.2 Redis 简介

Redis(RemoteDictionaryServer,远程字典型)是一个开源的、使用 C 语言编写的
NoSQL 数据库。Redis 基于内存运行并支持持久化,采用 key-value(键值对)的存储形式,是目前分布式架构中不可或缺的一环。

Redis 的优点:

  • 具有极高的数据读写速度,数据读取的速度最高可达到 110000 次/s,数据写入速度最高可达到 81000 次/s。
  • 支持丰富的数据类型,不仅仅支持简单的 key-value 类型的数据,还支持 Strings,Lists, Hashes, Sets 及 Ordered Sets 等数据类型操作。
  • 支持数据的持久化,可以将内存中的数据保存在磁盘中,重启的时候可以再次加载进行
    使用。
  • 原子性,Redis 所有操作都是原子性的。
  • 支持数据备份,即 master-salve 模式的数据备份。

1.3 Redis 安装部署(手工编译安装)

[root@localhost ~]# iptables -F 
[root@localhost ~]# setenforce 0
[root@localhost ~]# yum install gcc gcc-c++ make -y
将软件包拷贝到当前目录下
[root@localhost ~]# tar zvxf redis-5.0.7.tar.gz -C /opt
[root@localhost ~]# cd /opt/redis-5.0.7/
[root@localhost redis-5.0.7]# make
[root@localhost redis-5.0.7]# make PREFIX=/usr/local/redis install
[root@localhost redis-5.0.7]# ln -s /usr/local/redis/bin/* /usr/local/bin/
[root@localhost redis-5.0.7]# cd utils/
[root@localhost utils]# ./install_server.sh     ##安装服务脚本
Welcome to the redis service installer
This script will help you easily set up a running redis server

Please select the redis port for this instance: [6379]     ##选择redis默认接口,回车
Selecting default: 6379
Please select the redis config file name [/etc/redis/6379.conf]     ##redis默认配置文件名称,回车
Selected default - /etc/redis/6379.conf
Please select the redis log file name [/var/log/redis_6379.log]     ##默认redis日志文件名称,回车
Selected default - /var/log/redis_6379.log
Please select the data directory for this instance [/var/lib/redis/6379]    ##选择默认接口的默认数据文件,回车
Selected default - /var/lib/redis/6379
Please select the redis executable path [/usr/local/bin/redis-server]    ##选择redis可执行文件路径
Selected config:      ##选择的配置清单展示
Port           : 6379
Config file    : /etc/redis/6379.conf
Log file       : /var/log/redis_6379.log
Data dir       : /var/lib/redis/6379
Executable     : /usr/local/bin/redis-server
Cli Executable : /usr/local/bin/redis-cli
Is this ok? Then press ENTER to go on or Ctrl-C to abort.     ##确认ok,回车
Copied /tmp/6379.conf => /etc/init.d/redis_6379
Installing service...
Successfully added to chkconfig!
Successfully added to runlevels 345!
Starting Redis server...
Installation successful!
[root@localhost utils]# netstat -luntp | grep redis
tcp        0      0 127.0.0.1:6379          0.0.0.0:*               LISTEN      15552/redis-server

redis的启动管理命令

[root@localhost utils]# /etc/init.d/redis_6379 stop    ##停止
Stopping ...
Redis stopped
[root@localhost utils]# /etc/init.d/redis_6379 start    ##启动
Starting Redis server...
[root@localhost utils]# /etc/init.d/redis_6379 restart     ##重启
Stopping ...
Waiting for Redis to shutdown ...
Redis stopped
Starting Redis server...
[root@localhost utils]# /etc/init.d/redis_6379 status     ##状态
Redis is running (15775)

1.4 redis配置文件(/etc/redis/6379.conf)

redis在安装完成后,配置文件就已经将redis数据库基础使用的配置文件写好了,大致有以下几个常见的配置参数

  • bind:监听的主机地址
  • port:端口
  • daemonize yes:启用守护进程
  • pidfile:指定PID文件
  • loglevel notice:日志级别
  • logfile:指定日志文件
[root@localhost utils]# vim /etc/redis/6379.conf
bind 127.0.0.1
port 6379
daemonize yes
pidfile /var/run/redis_6379.pid
loglevel notice
logfile /var/log/redis_6379.log

二、 Redis常用命令

2.1 登录数据库

[root@localhost utils]# redis-cli 
127.0.0.1:6379>     ##默认是以配置文件中的回环地址登录
127.0.0.1:6379> keys *    ##查看键名
(empty list or set)
127.0.0.1:6379> quit    ##退出数据库

如果要以本地的IP地址登录数据库,要在配置文件的bind后面写上允许登录的IP

[root@localhost utils]# vim /etc/redis/6379.conf 
bind 127.0.0.1 14.0.0.7
[root@localhost utils]# /etc/init.d/redis_6379 restart 
Stopping ...
Waiting for Redis to shutdown ...
Redis stopped
Starting Redis server...
[root@localhost utils]# netstat -lntup | grep redis
tcp        0      0 14.0.0.7:6379           0.0.0.0:*               LISTEN      16051/redis-server  
tcp        0      0 127.0.0.1:6379          0.0.0.0:*               LISTEN      16051/redis-server

在这里插入图片描述
这时候使用本地IP登录数据库,登录成功

[root@localhost utils]# redis-cli -h 14.0.0.7 -p 6379     
14.0.0.7:6379> 

2.2 redis常用命令

14.0.0.7:6379> help set     ##help命令帮助查看命令用法

  SET key value [expiration EX seconds|PX milliseconds] [NX|XX]
  summary: Set the string value of a key
  since: 1.0.0
  group: string
14.0.0.7:6379> set name zhangsan     ##插入键名
OK
14.0.0.7:6379> keys *                ##查看键名
1) "name"
14.0.0.7:6379> get name              ##查看键值
"zhangsan"
14.0.0.7:6379> set color yellow
OK
14.0.0.7:6379> keys *
1) "color"
2) "name"
14.0.0.7:6379> del color             ##删除键名
(integer) 1                          ##操作成功返回一个非0值,不成功返回0
14.0.0.7:6379> keys *
1) "name"

redis数据库中也可以使用通配符,*表示所有,?表示单个字符

14.0.0.7:6379> keys na??
1) "name"
14.0.0.7:6379> keys n*
1) "name"

redis其他常用命令

14.0.0.7:6379> exists name     ##判断name这个键名是否存在
(integer) 1
14.0.0.7:6379> exists color
(integer) 0
14.0.0.7:6379> type name       ##查看键值的数据类型,默认情况下redis键值类型都是字符春string类型
string
14.0.0.7:6379> rename name Hello    ##对已有的key重命名
OK
14.0.0.7:6379> keys *
1) "Hello"
14.0.0.7:6379> dbsize                ##查看当前数据库key的数目
(integer) 1

1.3 redis-benchmark测试工具

  • -h:指定服务器主机名
  • -p︰指定服务器端口
  • -s:指定服务器 socket
  • -c:指定并发连接数
  • -n:指定请求数
  • -d:以字节的形式指定SET/GET值的数据大小
  • -q:强制退出Redis,仅显示query/sec值
  • -k:1=keep alive 0=reconnect
  • -r:SET/GET/INCR 使用随机 key, SADD 使用随机值
  • -P:通过管道传输请求
  • –csv:以 CSV 格式输出
  • -l:生成循环,永久执行测试
  • -t:仅运行以逗号分隔的测试命令列表
  • -I:Idle 模式。仅打开 N 个 idle 连接并等待

进行压力测试,主要看其中的get值与set值,分别代表读和写

[root@localhost utils]# redis-benchmark -h 14.0.0.7 -p 6379 -c 100 -n 100000    ##请求100000次,一次发100个请求
====== SET ======
  100000 requests completed in 0.92 seconds
  100 parallel clients
  3 bytes payload
  keep alive: 1

97.75% <= 1 milliseconds
99.85% <= 2 milliseconds
99.87% <= 3 milliseconds
99.89% <= 4 milliseconds
99.92% <= 5 milliseconds
99.94% <= 6 milliseconds
99.95% <= 7 milliseconds
99.97% <= 8 milliseconds
100.00% <= 8 milliseconds
108813.92 requests per second

====== GET ======
  100000 requests completed in 0.86 seconds
  100 parallel clients
  3 bytes payload
  keep alive: 1

99.37% <= 1 milliseconds
99.99% <= 2 milliseconds
100.00% <= 2 milliseconds
115874.86 requests per second

[root@localhost utils]# redis-benchmark -h 14.0.0.7 -p 6379 -q -d 100      ##测试存取大小为100字节的数据包的性能
PING_INLINE: 98814.23 requests per second
PING_BULK: 84175.09 requests per second
SET: 94250.71 requests per second
GET: 96618.36 requests per second
INCR: 101522.84 requests per second
LPUSH: 98911.96 requests per second
RPUSH: 100100.10 requests per second
LPOP: 97943.19 requests per second
RPOP: 97656.24 requests per second
SADD: 88028.16 requests per second
HSET: 94250.71 requests per second
SPOP: 101317.12 requests per second
LPUSH (needed to benchmark LRANGE): 97370.98 requests per second
LRANGE_100 (first 100 elements): 50200.80 requests per second
LRANGE_300 (first 300 elements): 20004.00 requests per second
LRANGE_500 (first 450 elements): 13858.09 requests per second
LRANGE_600 (first 600 elements): 10282.78 requests per second
MSET (10 keys): 106382.98 requests per second

1.4 多数据库操作

Redis 支持多数据库,Redis 在没有任何改动的情况下默认包含 16 个数据库,数据库名称是用数字 0-15 来依次命名的。使用 select 命令可以进行 Redis的多数据库之间的切换, 命令格式为 select index,其中 index 表示数据库的序号。而使用 redis-cli 连接 Redis 数据库后,默认使用的是序号为 0 的数据库。

多数据库间切换

[root@localhost utils]# redis-cli -h 14.0.0.7 -p 6379
14.0.0.7:6379> keys *
1) "mylist"
2) "myset:__rand_int__"
3) "World"
4) "key:__rand_int__"
5) "counter:__rand_int__"
14.0.0.7:6379> select 1    ##切换到序号为1的数据库
OK
14.0.0.7:6379[1]> keys *
(empty list or set)
14.0.0.7:6379[1]> set name zhangsan
OK
14.0.0.7:6379[1]> keys *
1) "name"
14.0.0.7:6379[1]> select 7    ##切换到序号为7的数据库
OK
14.0.0.7:6379[7]> keys *
(empty list or set)

1.5 设置hash结构

14.0.0.7:6379> hset person name zhangsan
(integer) 1
14.0.0.7:6379> hset person age 17
(integer) 1
14.0.0.7:6379> hset person score 99
(integer) 1
14.0.0.7:6379> keys *
1) "mylist"
2) "myset:__rand_int__"
3) "person"
4) "World"
5) "key:__rand_int__"
6) "counter:__rand_int__"
14.0.0.7:6379> hget person name
"zhangsan"
14.0.0.7:6379> hget person age
"17"
14.0.0.7:6379> hget person score
"99"

三、 Redis 持久化技术

3.1 持久化概述

Redis是运行在内存中,内存中的数据断电丢失为了能够重用Redis数据,或者防止系统故障,需要将Redis中的数据写入到磁盘空间中,即持久化。

Redis 的所有数据都是保存在内存中,然后不定期的通过异步方式保存到磁盘上(这称 为“半持久化模式”);也可以把每一次数据变化都写入到一个 append only file(aof)里面(这称 为“全持久化模式”)。

由于 Redis 的数据都存放在内存中,如果没有配置持久化,Redis 重启后数据就全丢失 了。所以,需要开启 Redis 的持久化功能,将数据保存到磁盘上,当 Redis 重启后,可以 从磁盘中恢复数据。Redis 提供两种方式进行持久化,一种是 RDB 持久化(原理是将 Reids 在内存中的数据库记录定时dump到磁盘上的RDB持久化), 另外一种是AOF(appendonly file)持久化(原理是将 Reids 的操作日志以追加的方式写入文件).

3.2 RDB 和 AOF 的区别

  • RDB 持久化是指在指定的时间间隔内将内存中的数据集快照写入磁盘,实际操作过程 是 fork 一个子进程,先将数据集写入临时文件,写入成功后,再替换之前的文件,用二进 制压缩存储。

  • AOF 持久化以日志的形式记录服务器所处理的每一个写、删除操作,查询操作不会记 录,以文本的方式记录,可以打开文件看到详细的操作记录

3.3 RDB 和 AOF 的优缺点

3.3.1 RDB优缺点

优点:

  • 采用该方式,整个 Redis 数据库将只包含一个文件,一旦系统出现灾难性故障,可以非常容易地进行恢复。
  • 对于灾难恢复而言,RDB 可以非常轻松的将一个单独的文件压缩后再转移到其它存储介质上
  • 性能最大化,对于 Redis 的服务进程而言,在开始持久化时,它唯一需要做的只是 fork出子进程,之后再由子进程完成这些持久化的工作,这样就可以极大的避免服务进程执 行 IO 操作
  • 相比于 AOF 机制,如果数据集很大,RDB 的启动效率会更高。

缺点:

  • 如果想保证数据的高可用性,即最大限度的避免数据丢失,那么 RDB 将不是一个很好
    的选择。因为系统一旦在定时持久化之前出现宕机现象,此前没有来得及写入磁盘的数
    据都将丢失。
    由于 RDB 是通过 fork 子进程来协助完成数据持久化工作的,因此当数据集较大时,可 能会导致整个服务器停止服务几百毫秒,甚至是 1 秒钟。

3.3.1 AOF优缺点

优点:

  • AOF 机制可以带来更高的数据安全性,即数据持久性。Redis 中提供了 3 种同步策略,即每秒同步、每次修改同步和不同步。事实上,每秒同步也是异步完成的,其效率也是非常高的,弊端是一旦系统出现宕机现象,那么这一秒钟之内修改的数据将会丢失。而每次修改同步,可以将其视为同步持久化,即每次发生的数据变化都会被立即记录到磁盘中,这种方式在效率上是最低的。
  • 由于该机制对日志文件的写入操作采用的是 append 模式,因此在写入过程中即使出现宕机现象,也不会破坏日志文件中已经存在的内容。然而如果本次操作只是写入了一半 数据就出现了系统崩溃问题,那么在 Redis 下一次启动之前,可以通过 redis-check-aof工具来解决数据一致性的问题。如果日志过大,Redis 可以自动启用 rewrite 机制。即 Redis 以 append 模式不断地将 修改数据写入到老的磁盘文件中,同时 Redis 还会创建一个新的文件用于记录此期间 有哪些修改命令被执行。因此在进行 rewrite 切换时可以更好的保证数据安全性。
  • AOF 包含一个格式清晰、易于理解的日志文件用于记录所有的修改操作。事实上,也可以通过该文件完成数据的重建。

缺点:

  • 对于相同数量的数据集而言,AOF 文件通常要大于 RDB 文件。RDB 在恢复大数据集 时的速度比 AOF 的恢复速度要快。
  • 根据同步策略的不同,AOF 在运行效率上往往会慢于 RDB。每秒同步策略的效率是比 较高的,同步禁用策略的效率和 RDB 一样高效。

3.4 Redis 持久化配置

3.4.1 RDB 持久化配置

Redis 会将数据集的快照 dump 到 dump.rdb 文件中。此外,也可以通过配置文件来修 改 Redis 服务器 dump 快照的频率。

[root@localhost utils]# vim /etc/redis/6379.conf
save 900 1    ##在 900 (15 分钟)之后,如果至少有 1  key 发生变化,则 dump
内存快照。 
save 300 10    ##在 300 (5 分钟)之后,如果至少有 10  key 发生变化,则 dump内存快照
save 60 10000    ##在 60 (1 分钟)之后,如果至少有 10000  key 发生变化,则 dump 内存快照。

在这里插入图片描述

3.4.2 AOF持久化配置

在 Redis 的配置文件中存在三种同步方式

  • appendfsync always:每次有数据修改发生时都会写入 AOF 文件。
  • appendfsynceverysec:每秒钟同步一次,该策略为 AOF 的缺省策略。
  • appendfsync no:从不同步,高效但是数据不会被持久化。

Redis 会不断地将被执行的命令记录到 AOF 文件里面,所以随着 Redis 不断运行, AOF 文件的体积也会不断增长。在极端情况下,体积不断增大的 AOF 文件甚至可能会用完硬盘的所有可用空间,用户可以向 Redis 发送 BGREWRITEAOF 命令。BGREWRITEAOF 命令会通过移除 AOF 文件中的冗余命令来重写(rewrite)AOF 文件,使 AOF 文件的体积尽可能地变小。

AOF 持久化可以通过设置 auto-aof-rewrite-percentage 选项和 auto-aof-rewrite-min-size 选项来自动执行 BGREWRITEAOF。

四、 Redis 性能管理

Redis 性能管理需要关注的数据指标有内存使用率、内存碎片率、回收 key 等。

我们可以使用命令 info memory 来查看Redis的部分信息

14.0.0.7:6379> info memory
# Memory
used_memory:11767568
used_memory_human:11.22M
used_memory_rss:20930560
used_memory_rss_human:19.96M
used_memory_peak:24931720
used_memory_peak_human:23.78M
used_memory_peak_perc:47.20%
used_memory_overhead:841470
used_memory_startup:791400
used_memory_dataset:10926098
used_memory_dataset_perc:99.54%
allocator_allocated:12203024
allocator_active:12582912
allocator_resident:20201472
total_system_memory:3954188288
total_system_memory_human:3.68G
used_memory_lua:37888
used_memory_lua_human:37.00K
used_memory_scripts:0
used_memory_scripts_human:0B
number_of_cached_scripts:0
maxmemory:0
maxmemory_human:0B
maxmemory_policy:noeviction
allocator_frag_ratio:1.03
allocator_frag_bytes:379888
allocator_rss_ratio:1.61
allocator_rss_bytes:7618560
rss_overhead_ratio:1.04
rss_overhead_bytes:729088
mem_fragmentation_ratio:1.78
mem_fragmentation_bytes:9204016
mem_not_counted_for_evict:0
mem_replication_backlog:0
mem_clients_slaves:0
mem_clients_normal:49694
mem_aof_buffer:0
mem_allocator:jemalloc-5.1.0
active_defrag_running:0
lazyfree_pending_objects:0
14.0.0.7:6379> 

4.1 内存碎片率

mem_fragmentation_ratio 给出了内存碎片率的数据指标,它是由操系统 分配的内存值 used_memory_rss 除以 Redis 使用的内存值 used_memory 得出的。内存值 used_memory_rss中的rss是ResidentSetSize的缩写, 表示该进程所占物理内存的大小。

内存碎片是由操作系统低效的分配/回收物理内存导致的。操作系统负责分配物理内存给各个应用进程,Redis 使用的内存与物理内存的映射是由操作系统上虚拟内存管理分配器完成的。

比如:Redis 需要分配连续内存块来存储 1G 的数据集。如果物理内存上没有超过 1G 的连续内存块,那操作系统就不得不使用多个不连续的小内存块来分配并存储这 1G 数
据,该操作就会导致内存碎片的产生。

内存碎片率稍大于 1 是合理 的,这个值表示内存碎片率比较低,也说明 Redis 没有发生内存交换。但如果内存碎片率超过 1.5,那就说明 Redis 消耗了实际需要物理内存的 150%,其中 50%是内存碎片率。若 是内存碎片率低于 1 的话,说明 Redis 内存分配超出了物理内存,操作系统正在进行内存交换。内存交换会引起非常明显的响应延迟。

  • 内存碎片率超过 1.5
    重启 Redis 服务器可以让额外产生的内存碎片失效并重新作为新内存来使用, 使操作系统恢复高效的内存管理
  • 如果内存碎片率低于 1
    Redis 实例可能会把部分数据交换到硬盘上。内存交换会严重影响 Redis 的性 能,所以应该增加可用物理内存或减少 Redis 内存占用

4.2 内存使用率

内存使用率是 Redis 服务最关键的一部分。如果一个 Redis 实例的内存使用率超过可 用最大内存,那么操作系统开始进行内存与 swap 空间交换,把内存中旧的或不再使用的内 容写入硬盘上(硬盘上的这块空间叫 swap 分区),这样会导致读写的效率骤然降低。

通过查看 used_memory 指标可知道 Redis 正在使用的内存情况,如果 used_memory 大于可用最大 内存,那就说明 Redis 实例正在进行内存交换或者已经完成内存交换。

避免内存交换:

  • 针对缓存数据大小选择

  • 使用 Hash数据结构

  • 设置 key 的过期时间

4.3 回收key

当内存使用达到设置的最大阀值时,需要选择一种 key 的回收策略,可在 redis.conf 配置文件中修改“maxmemory-policy”属性值。默认情况下回收策略是禁止删除,若是 Redis 数据集中的 key 都设置了过期时间,那么“volatile-ttl”策略是比较好的选择。但如果 key 在达到最大内存限制时没能够迅速过期,或者根本没有设置过期时间。那么设置为“allkeys-lru” 值比较合适,它允许 Redis 从整个数据集中挑选最近最少使用的 key 进行删除(LRU 淘汰算 法)。Redis 还提供了一些其他淘汰策略。

  • volatile-lru:使用 LRU 算法从已设置过期时间的数据集合中淘汰数据;
  • volatile-ttl:从已设置过期时间的数据集合中挑选即将过期的数据淘汰;
  • volatile-random:从已设置过期时间的数据集合中随机挑选数据淘汰;
  • allkeys-lru:使用 LRU 算法从所有数据集合中淘汰数据;
  • allkeys-random:从数据集合中任意选择数据淘汰;
  • no-enviction:禁止淘汰数据。
[root@localhost utils]# vim /etc/redis/6379.conf
 maxmemory-policy volatile-ttl

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/kimowinter/article/details/108475001