Redis(Remote Dictionary Server ),即远程字典服务,是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。从2010年3月15日起,Redis的开发工作由VMware主持。从2013年5月开始,Redis的开发由Pivotal赞助。
是一种非关系型数据库,是一种内存/缓存数据库,数据保存在内存中,但是可以定期将数据写入硬盘。
redis优势
支持内存缓存,有极高的数据读写速度
支持持久化保存,可以存储对象
支持集群、分布式
数据类型更多
支持数据备份
具有原子性
支持队列
[root@localhost bao]# yum -y install gcc gcc-c++ make
[root@localhost bao]# rz -E
rz waiting to receive.
[root@localhost bao]# ls
redis-5.0.7.tar.gz
[root@localhost bao]# tar zxvf redis-5.0.7.tar.gz
…省略解压过程…
[root@localhost bao]# cd redis-5.0.7/
[root@localhost redis-5.0.7]# ls
00-RELEASENOTES deps README.md runtest-moduleapi tests
BUGS INSTALL redis.conf runtest-sentinel utils
CONTRIBUTING Makefile runtest sentinel.conf
COPYING MANIFESTO runtest-cluster src
[root@localhost redis-5.0.7]# make ##没有con啥的脚本文件,那就直接make吧
[root@localhost redis-5.0.7]# make install PREFIX=/usr/local/redis ##指定安装目录
[root@localhost redis-5.0.7]# cd /usr/local/redis/
[root@localhost redis]# ls
bin
[root@localhost redis]# cd bin/
[root@localhost bin]# ls ##看看这六个文件齐不齐
redis-benchmark redis-check-rdb redis-sentinel
redis-check-aof redis-cli redis-server
[root@localhost bin]# cd /bao/redis-5.0.7/utils/
[root@localhost utils]# ls
build-static-symbols.tcl hashtable redis_init_script.tpl
cluster_fail_time.tcl hyperloglog redis-sha1.rb
corrupt_rdb.c install_server.sh releasetools
create-cluster lru speed-regression.tcl
generate-command-help.rb redis-copy.rb whatisdoing.sh
graphs redis_init_script
[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]
Selecting default: 6379
Please select the redis config file name [/etc/redis/6379.conf]
Selected default - /etc/redis/6379.conf
Please select the redis log file name [/var/log/redis_6379.log]
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/redis/bin/redis-server ##手敲,bin可执行文件
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/redis/bin/redis-server ##可执行脚本文件
Cli Executable : /usr/local/redis/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]# cd /etc/init.d/ ##在init.d下可以看到redis的脚本,证明可以被service控制
[root@localhost init.d]# ls |grep redis
redis_6379
[root@localhost init.d]# service redis_6379 stop
/var/run/redis_6379.pid does not exist, process is not running
[root@localhost init.d]# service redis_6379 start
Starting Redis server...
[root@localhost init.d]# netstat -ntuap |grep 6379
tcp 0 0 127.0.0.1:6379 0.0.0.0:* LISTEN 77279/redis-server
设置监听端口,查看数据库是否可以成功进入
[root@localhost init.d]# vim /etc/redis/6379.conf
# Examples: ##这个下面的两个注释掉的bind是redis给的模板,不用修改
#
# bind 192.168.1.100 10.0.0.1
# bind 127.0.0.1 ::1
70 bind 127.0.0.1 20.0.0.6 ##要改的在第70行
[root@localhost init.d]# service redis_6379 restart
Stopping ...
Waiting for Redis to shutdown ...
Redis stopped
Starting Redis server...
[root@localhost init.d]# ln -s /usr/local/redis/bin/* /usr/local/bin
[root@localhost init.d]# redis-cli -h 20.0.0.6 -p 6379
20.0.0.6:6379> ##可以正常进入数据库了
[root@localhost init.d]# redis-cli -h 20.0.0.6 -p 6379
20.0.0.6:6379> help set ##查看命令帮助
SET key value [expiration EX seconds|PX milliseconds] [NX|XX]
summary: Set the string value of a key
since: 1.0.0
group: string
20.0.0.6:6379> set gunpla 00Q ##创建 key键 值
OK
20.0.0.6:6379> set gundam EXIA
OK
20.0.0.6:6379> keys * ##查看所有 键
1) "gunpla"
2) "gundam"
20.0.0.6:6379> RENAME gunpla gaoda ##重命名 gunpla 为 gaoda
OK
20.0.0.6:6379> del gundam ##删除 gundam 键
(integer) 1
20.0.0.6:6379> keys *
1) "gaoda"
库 操作
20.0.0.6:6379> SELECT 10 ##切换到 第 10 库
OK
20.0.0.6:6379[10]> keys *
(empty list or set)
20.0.0.6:6379[10]> set GUNDAM00 00RAISE
OK
20.0.0.6:6379[10]> MOVE GUNDAM00 9 ##移动 键 到 第9库
(integer) 1 ##操作状态码 成功返回 非0,不成功返回 0
20.0.0.6:6379[11]> SELECT 9
OK
20.0.0.6:6379[9]> KEYS *
1) "GUNDAM00"
20.0.0.6:6379[9]> GET GUNDAM00 ##查看 键值
"00RAISE"
20.0.0.6:6379[9]> FLUSHALL ##清空库方法 ①
OK
20.0.0.6:6379[9]> keys *
(empty list or set)
20.0.0.6:6379[9]> SELECT 0
OK
20.0.0.6:6379> set caicai 180
OK
20.0.0.6:6379> keys *
1) "caicai"
20.0.0.6:6379> FLUSHDB ##清空库方法 ②
OK
20.0.0.6:6379> KEYS *
(empty list or set)
压力测试
使用 redis-benchmark 测试工具
-h 指定主机IP
-p 指定端口
-c 指定并发连接数
-n 指定请求数
-d 以字节形式指定 SET/GET 的值数据大小
-q 强制退出 redis,仅显示 query/sec 的值
[root@localhost init.d]# redis-benchmark -h 20.0.0.6 -p 6379 -c 100 -n 10000 ##并发量 100,请求量 10000
……省略部分
====== SET ====== ##写入速度
10000 requests completed in 0.12 seconds ##耗时
100 parallel clients
3 bytes payload
keep alive: 1
97.86% <= 1 milliseconds
99.24% <= 2 milliseconds
99.79% <= 3 milliseconds
100.00% <= 3 milliseconds
86956.52 requests per second
====== GET ====== ##读取速度
10000 requests completed in 0.11 seconds ##耗时
100 parallel clients
3 bytes payload
keep alive: 1
99.92% <= 1 milliseconds
100.00% <= 1 milliseconds
87719.30 requests per second
省略部分……
[root@localhost init.d]# redis-benchmark -h 20.0.0.6 -p 6379 -q -d 100
##-q 强制退出redis,-d 指定字节数量
…省略部分
SET: 85616.44 requests per second
GET: 86655.11 requests per second
省略部分…
hash 结构
20.0.0.6:6379> hset yaoshi Asuo yihao
(integer) 1
20.0.0.6:6379> hset demaxiya gaolun 190
(integer) 1
20.0.0.6:6379> hset demaxiya kuiyin 160
(integer) 1
20.0.0.6:6379> hset demaxiya huangzi 185
(integer) 1
20.0.0.6:6379> hget demaxiya gaolun
"190"
20.0.0.6:6379> hget demaxiya huangzi
"185"
数据持久化概述
Redis 原本是运行在内存中,机器断电则数据丢失
为了可以保护Redis数据,防止系统故障,需将Redis中的数据写入硬盘中,这种操作就叫做持久化
持久化分类
RBD是 redis 默认的持久化方式
默认备份文件名 dump.rdb,位置 /var/lib/redis/6379
触发条件如下
在指定的时间间隔内,执行指定次数的写操作(配置文件里可以改)
执行 save 或者 bgsave 命令
执行 flushall 命令,清空数据库所有数据
执行 shutdown 命令,保证服务器正常关闭且不丢失任何数据
优缺点
[root@localhost init.d]# vim /etc/redis/6379.conf
217 # save ""
218
219 save 900 1 ##900秒之内至少进行了一次写操作
220 save 300 10 ##300秒内至少进行了10次写操作
221 save 60 10000 ##60秒内至少进行10000次写操作
253 # The filename where to dump the DB
254 dbfilename dump.rdb ##RBD文件名
251 rdbchecksum yes ##压缩功能开启
264 dir /var/lib/redis/6379 ##RDB文件位置
[root@localhost init.d]# cd /var/lib/redis/6379/
[root@localhost 6379]# ls
dump.rdb
Redis默认不开启
弥补RDB的不足(数据的不一致性)
采用日志的形式来记录每个写操作,并追加到文件中
Redis重启会根据日志文件的内容将写指令从前到后执行一次以完成数据的恢复工作
根据AOF文件恢复数据
将appendonly.aof文件拷贝到redis安装目录的bin目录下,重启redis服务即可
AOF重写机制
概述
AOF的工作原理是将写操作追加到文件中,文件的冗余内容会越来越多
当AOF文件的大小超过所设定的阀值时,Redis就会对AOF文件的内容压缩
原理
Redis会fork出一条新进程,读取内存中的数据(并没有读取旧文件),并重新写到一个临时文件中,最后替换旧的aof文件
[root@localhost ~]# vim /etc/redis/6379.conf
700 appendonly yes ##默认为no,改成yus开启持久化
704 appendfilename "appendonly.aof" ##文件名称
729 # appendfsync always ##同步持久化,每次发生数据变化会立刻写入磁盘
730 appendfsync everysec ##默认推荐,每秒异步记录次,默认值
731 # appendfsync no ##不同步,交给操作系统决定如何同步
752 no-appendfsync-on-rewrite no ##在日志进行BGREWRITEAOF时, 如果设置为yes表示新写操作不进行同步fsync,只暂存在缓冲区里,避免造成磁盘I0操作冲突,等重写完成后在写入,redis中默认为no
771 auto-aof-rewrite-percentage 100 ##当前AOF文件大小是上次日志重写时AOF文件大小两倍时,发生BGREWRITEAOF操作
772 auto-aof-rewrite-min-size 64mb ##当前AOF文件执行BGREWRITEAOF命令的最小值,避免刚开始启动Reids时由于文件尺寸较小导致频繁的BGREWRITEAOF.当AOF文件到达64M的时候,发生BGREWRITEAOF操作
796 aof-load-truncated yes ##忽略最后一条可能存在问题的指令
将appendonly.aof文件拷贝到redis安装目录的bin目录下,重启redis服务即可,就可以恢复数据了
[root@localhost ~]# cd /var/lib/redis/6379/
[root@localhost 6379]# ls
appendonly.aof dump.rdb
127.0.0.1:6379> INFO MEMORY
# Memory
used_memory:853504 ##Redis使用其分配器分配的内存大小,已经使用了的内存大小
used_memory_human:833.50K ##用户数据所占用的内存,就是你缓存的数据的大小
used_memory_rss:12820480 ##操作系统分配给Redis实例的内存大小,表示该进程所占物理内存的大小
used_memory_rss_human:12.23M
used_memory_peak:853504
used_memory_peak_human:833.50K
used_memory_peak_perc:100.01%
used_memory_overhead:841280
used_memory_startup:791416
used_memory_dataset:12224
used_memory_dataset_perc:19.69%
allocator_allocated:1608480
allocator_active:2019328
allocator_resident:9019392
total_system_memory:1907970048
total_system_memory_human:1.78G
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.26
allocator_frag_bytes:410848
allocator_rss_ratio:4.47
allocator_rss_bytes:7000064
rss_overhead_ratio:1.42
rss_overhead_bytes:3801088
mem_fragmentation_ratio:15.78 ##内存碎片率,内存疑惑行为???
mem_fragmentation_bytes:12007992
mem_not_counted_for_evict:98
mem_replication_backlog:0
mem_clients_slaves:0
mem_clients_normal:49694
mem_aof_buffer:98
mem_allocator:jemalloc-5.1.0
active_defrag_running:0
lazyfree_pending_objects:0
操系统分配的内存值used_ memory rss除以redis使用的内存值
used _memory计算得出
内存碎片是由操作系统低效的分配/回收物理内存导致的
不连续的物理内存分配
跟踪内存碎片率对理解redis实例的资源性能是非常重要的
内存碎片率稍大于1是合理的,这个值表示内存碎片率比较低
内存碎片率超过1.5,说明redis消耗了实际需要物理内存的150%,其中50%是内存碎片率
内存碎片率低于1的,说明Redis内存分配超出了物理内存,操作系统正在进行内存交换
我这边看到一篇写的挺详细的,图也是拿的他的,链接放这了
点这里
碎片过高解决方法
1、重启Redis服务器可以让额外产生的内存碎片失效并重新作为新内存来使用,使操作系统恢复高效的内存管理修改内存分配器。
redis支持glibc’s malloc、jemalloc11、tcmalloc几种不同的内存分配器,每个分配器在内存分配和碎片上都有不同的实现。不建议普通管理员修改Redis默认内存分配器,因为这需要完全理解这几种内存分配器的差异,也要重新编译Redis
2、redis4.0以上可以使用新增指令来手动回收内存碎片,配置监控使用性能更佳。
警告此功能是实验性的。然而,即使在生产中也进行了压力测试,并且由多个工程师手动测试了一段时间
3、自动(实时)碎片整理允许Redis服务器压缩内存中小数据分配和数据释放之间的空间,从而允许回收内存。
[root@localhost 6379]# vim /etc/redis/6379.conf
1353 activedefrag yes
redis实例的内存使用率超过可用最大内存,操作系统将开始进行
内存与swap空间交换
避免内存交换
针对缓存数据大小选择
尽可能的使用Hash数据结构
设置key的过期时间
保证合理分配redis有限的内存资源
当内存使用达到设置的最大阀值时,需要选择一种key的回收策略
默认情况下回收策略是禁止删除
redis.conf配置文件中修改maxmemory-policy属性值
volatile-lru:使用LRU算法从已设置过期时间的数据集合中淘汰数据
volatile-ttl:从已设置过期时间的数据集合中挑选即将过期的数据淘汰(建议使用)
volatile-random:从已设置过期时间的数据集合中随机挑选数据淘汰
allkeys-lru:使用LRU算法从所有数据集合中淘汰数据
allkeys-random:从数据集合中任意选择数据淘汰
no-enviction:禁止淘汰数据