Redis 数据库是一个非关系型数据库。
数据库按照数据库的结构可以分为关系型数据库与其他数据库,而这些其他数据库统称为非关系型数据库。
关系型数据库是一个结构化的数据库,创建在关系模型基础上,一般面向于记录。它借 助于集合代数等数学概念和方法来处理数据库中的数据。关系模型就是指二维表格模型,因而一个关系型数据库就是由二维表及其之间的联系组成的一个数据组织。现实世界中,各种实体与实体之间的各种联系都可以用关系模型来表示。SQL 语句(标准数据查询语言)就是一种基于关系型数据库的语言,用于执行对关系型数据库中数据的检索和操作。
主流的关系型数据库包括 Oracle、MySQL、SQLServer、MicrosoftAccess、DB2 等。
NoSQL(NoSQL=Not Only SQL),意思是“不仅是 SQL”,是非关系型数据库的总称。 主流的 NoSQL 数据库有 Redis、MongBD、Hbase、CouhDB 等等,他们的存储方式、存储结构以及使用的场景都是完全不同的。所以我们认为它是一个非关系型数据库的集合。总而言之,除了主流的关系型数据库以外的数据库,都可以认为是非关系型数据库。
High performance——对数据库高并发读写需求
Huge Storage——对海量数据高效存储与访问需求
High Scalability && HighAvailability——对数据库高可扩展性与高可用性需求
Redis(RemoteDictionaryServer,远程字典型)是一个开源的、使用 C 语言编写的
NoSQL 数据库。Redis 基于内存运行并支持持久化,采用 key-value(键值对)的存储形式,是目前分布式架构中不可或缺的一环。
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)
redis在安装完成后,配置文件就已经将redis数据库基础使用的配置文件写好了,大致有以下几个常见的配置参数
[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
[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
[root@localhost utils]# redis-cli -h 14.0.0.7 -p 6379
14.0.0.7:6379>
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
进行压力测试,主要看其中的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
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)
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是运行在内存中,内存中的数据断电丢失为了能够重用Redis数据,或者防止系统故障,需要将Redis中的数据写入到磁盘空间中,即持久化。
Redis 的所有数据都是保存在内存中,然后不定期的通过异步方式保存到磁盘上(这称 为“半持久化模式”);也可以把每一次数据变化都写入到一个 append only file(aof)里面(这称 为“全持久化模式”)。
由于 Redis 的数据都存放在内存中,如果没有配置持久化,Redis 重启后数据就全丢失 了。所以,需要开启 Redis 的持久化功能,将数据保存到磁盘上,当 Redis 重启后,可以 从磁盘中恢复数据。Redis 提供两种方式进行持久化,一种是 RDB 持久化(原理是将 Reids 在内存中的数据库记录定时dump到磁盘上的RDB持久化), 另外一种是AOF(appendonly file)持久化(原理是将 Reids 的操作日志以追加的方式写入文件).
RDB 持久化是指在指定的时间间隔内将内存中的数据集快照写入磁盘,实际操作过程 是 fork 一个子进程,先将数据集写入临时文件,写入成功后,再替换之前的文件,用二进 制压缩存储。
AOF 持久化以日志的形式记录服务器所处理的每一个写、删除操作,查询操作不会记 录,以文本的方式记录,可以打开文件看到详细的操作记录
优点:
缺点:
优点:
缺点:
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 内存快照。
在 Redis 的配置文件中存在三种同步方式
Redis 会不断地将被执行的命令记录到 AOF 文件里面,所以随着 Redis 不断运行, AOF 文件的体积也会不断增长。在极端情况下,体积不断增大的 AOF 文件甚至可能会用完硬盘的所有可用空间,用户可以向 Redis 发送 BGREWRITEAOF 命令。BGREWRITEAOF 命令会通过移除 AOF 文件中的冗余命令来重写(rewrite)AOF 文件,使 AOF 文件的体积尽可能地变小。
AOF 持久化可以通过设置 auto-aof-rewrite-percentage 选项和 auto-aof-rewrite-min-size 选项来自动执行 BGREWRITEAOF。
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>
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 内存分配超出了物理内存,操作系统正在进行内存交换。内存交换会引起非常明显的响应延迟。
内存使用率是 Redis 服务最关键的一部分。如果一个 Redis 实例的内存使用率超过可 用最大内存,那么操作系统开始进行内存与 swap 空间交换,把内存中旧的或不再使用的内 容写入硬盘上(硬盘上的这块空间叫 swap 分区),这样会导致读写的效率骤然降低。
通过查看 used_memory 指标可知道 Redis 正在使用的内存情况,如果 used_memory 大于可用最大 内存,那就说明 Redis 实例正在进行内存交换或者已经完成内存交换。
避免内存交换:
针对缓存数据大小选择
使用 Hash数据结构
设置 key 的过期时间
当内存使用达到设置的最大阀值时,需要选择一种 key 的回收策略,可在 redis.conf 配置文件中修改“maxmemory-policy”属性值。默认情况下回收策略是禁止删除,若是 Redis 数据集中的 key 都设置了过期时间,那么“volatile-ttl”策略是比较好的选择。但如果 key 在达到最大内存限制时没能够迅速过期,或者根本没有设置过期时间。那么设置为“allkeys-lru” 值比较合适,它允许 Redis 从整个数据集中挑选最近最少使用的 key 进行删除(LRU 淘汰算 法)。Redis 还提供了一些其他淘汰策略。
[root@localhost utils]# vim /etc/redis/6379.conf
maxmemory-policy volatile-ttl