概述
Redis是一个基于key-value键值对的持久化数据库存储系统。redis支持的数据存储类型比memcached更丰富,包括strings(字符串),lists(列表),sets(集合)和sorted sets(有序集合)等。
这些数据类型支持push/pop,add/remove及取交集,并集和差集及更丰富的操作,而且这些操作都是原子性的。在此基础上,redis支持各种不同方式的排序。与memcached缓存服务一样,为了保证效率,数据都是缓存在内存中提供服务。和memcached不同的是,redis持久化缓存服务还会周期性的把更新的数据写入到磁盘以及把修改的操作记录追加到文件里记录下来,比memcached更有优势的是,redis还支持master-slave(主从)同步,这点很类似关系型数据库MySQL主从复制功能
Redis是一个开源的使用C语言编写(3万多行代码),支持网络,可基于内存亦可持久化的日志型,Key-Value数据库,并提供多种语言的API。从2010年3月15日起,Redis的开发工作由VMware主持。
Redis软件的出现,再一定程度上弥补了memcached这类key-value内存缓存服务的不足,在部分场合可以对关系数据库起到很好的补充作用。redis提供了Python,Ruby,Erlang,PHP客户端,使用起来很方便.
redis特点
1.key-value键值类型存储
2.支持数据可靠存储及落地
3.单进程单线程高性能服务器
4.crash safe & recovery slow
5.单机qps可以达到10W
6.适合小数据量高速读写访问
Redis优点
1.与memcached不同,Redis可以持久化存储数据
2.性能很高:Redis能支持超过10W每秒的读写频率。
3.丰富的数据类型:Redis支持二进制的Strings,Lists,Hashes,Sets及sorted Sets等数据类型操作
4.原子:Redis的所有操作都是原子性的,同时Redis还支持对几个操作全并后的原子性执行
5.丰富的特性:Redis还支持publish/subscribe(发布/订阅),通知,key过期等等特性。
6.redis支持异机主从复制。
redis缺陷与陷阱
1.系统运行有毛刺
2.不同命令延迟差别极大
3.内存管理开销大(设置低于物理内存3/5)
4.buffer io造成系统OOM(内存溢出)
redis的数据类型
作为Key-value型存储系统数据库,Redis提供了键(Key)和值(value)映射关系。但是,除了常规的数值或字符串,Redis的键值还可以是以下形式之一,下面为最为常用的数据类型:
- String 字符串
- Hash 哈希表
- List 列表
- Set 集合
- Sorted set 有序集合
redis 持久化
通常,Redis将数据存储于内存中,或被配置为使用虚拟内存。通过两种方式可以实现数据持久化:
使用快照(snapshot)的方式,将内存中的数据不断写入磁盘,或使用类似MySQL的binlog日志
aof (但并不用于主从同步)方式,记录每次更新的日志。前者性能较高,但是可能会引起一定程度的数据丢失;后者相反。
#Snapshot(快照) save 900 1 #900秒有1key容量被更新,则触发快照写入磁盘 save 300 10 save 60 10000
#AOF(更新日志) appendfsync always #总是记录更新内容 appendfsync everysec #每秒记录更新内容 appendfsync no #不记录更新内容
特别提示:
如果选择了快照的策略,那么快照在每次进行保存的时候,都会阻碍执行前端的客户端请求。 快照会一次性将内存里的数据全都写进磁盘。
Redis的生产经验教训
1.一定要进行Master-slave主从同步配置,在出现服务故障时可以切换
2.在master禁用数据持久化,只需要在slave上配置数据持久化
3.物理内存+虚拟内存不足,这个时候dump一直死着,时间久了机器挂掉。这个情况就是灾难!
4.当Redis物理内存使用超过内存总容量的3/5时就会开始比较危险了,就开始做swap,内存碎片大!
5.当达到最大内存时,会清空带有过期时间的key,即使key未到过期时间。
6.redis与DB同步写的问题,先写DB,后写redis,因为写内存基本上没有问题。
Redis的服务器4.0版本源码编译安装
系统:Centos7
版本:redis4.0
redis下载地址:https://redis.io/download
redis源码编译
yum -y install wget gcc gcc-c++ make tar openssl-devel cmake tar xf redis-4.0.10.tar.gz -C /usr/src/ cd /usr/src/redis-4.0.10/ make;make MALLOC=jemalloc;make PREFIX=/usr/local/redis install mkdir -p /usr/local/redis/conf cp /usr/src/redis-4.0.10/redis.conf /usr/local/redis/conf/ cp /usr/src/redis-4.0.10/sentinel.conf /usr/local/redis/conf/ ln -s /usr/local/redis/bin/* /usr/local/bin/
redis-server --version #服务端连接命令 Redis server v=4.0.10 sha=00000000:0 malloc=jemalloc-4.0.3 bits=64 build=d2228e273f4aff2f
redis-cli --version #客户端连接命令 redis-cli 4.0.10
编译安装命令执行完成之后,会在/usr/local/redis/bin/目录下生成5个可执行文件,分别是:
redis-server #Redis服务器的daemon启动程序 redis-cli #Redis命令操作工具。当然,你也可以用telnet根据其纯文本协议来操作 redis-benchmark #Redis性能测试工具,测试Redis在你的系统及你的配置下的读写性能。 redis-check-aof #对更新日志appendonly.aof检查,是否可用,类似检查mysql binlog的工具 redis-check-dump #用于本地数据库rdb文件的检查
Redis的服务器启动和系统参数调整
简化redis配置文件
cp /usr/local/redis/conf/redis.conf{,.bak} #备份配租文件 egrep -v "^$|^#" /usr/local/redis/conf/redis.conf.bak > /usr/local/redis/conf/redis.conf #简化配置文件 mkdir -p /data/redis/ #创建redis数据目录
更改redis配置文件/usr/local/redis/conf/redis.conf
#修改redis配置文件以下参数 cat -n conf/redis.conf | sed -n '1p;3p;4p;7p;9p;11p;21p' 1 bind 127.0.0.1 3 port 6379 4 tcp-backlog 511 7 daemonize no 9 pidfile /var/run/redis_6379.pid 11 logfile "" 21 dir ./ #修改成以下设置 cat -n conf/redis.conf | sed -n '1p;3p;4p;7p;9p;11p' 1 bind 0.0.0.0 #监听地址 3 port 6379 #监听端口 4 tcp-backlog 1024 #tcp连接数 7 daemonize yes #是否后台启动 9 pidfile /data/redis/redis.pid #pid存放目录 11 logfile "/data/redis/redis.log" #日志存放目录 21 dir /data/redis/ #工作目录
redis服务器启动和关闭
#启动redis服务器 redis-server /usr/local/redis/conf/redis.conf netstat -antup | grep redis #关闭redis服务器 redis-cli shutdown netstat -antup | grep redis #连接redis服务器 redis-server /usr/local/redis/conf/redis.conf redis-cli -h 127.0.0.1
系统参数优化调整
#启动redis以后,我们查看系统日志 cat /data/redis/redis.log cat /data/redis/redis.log 7702:C 20 Aug 04:09:02.029 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo 7702:C 20 Aug 04:09:02.029 # Redis version=4.0.10, bits=64, commit=00000000, modified=0, pid=7702, just started 7702:C 20 Aug 04:09:02.029 # Configuration loaded 7703:M 20 Aug 04:09:02.033 * Increased maximum number of open files to 10032 (it was originally set to 1024).
#警告提示1:系统文件描述符设置的太小了,才1024,我们最好设置到10032 _._ _.-``__ ''-._ _.-`` `. `_. ''-._ Redis 4.0.10 (00000000/0) 64 bit .-`` .-```. ```/ _.,_ ''-._ ( ' , .-` | `, ) Running in standalone mode |`-._`-...-` __...-.``-._|'` _.-'| Port: 6379 | `-._ `._ / _.-' | PID: 7703 `-._ `-._ `-./ _.-' _.-' |`-._`-._ `-.__.-' _.-'_.-'| | `-._`-._ _.-'_.-' | http://redis.io `-._ `-._`-.__.-'_.-' _.-' |`-._`-._ `-.__.-' _.-'_.-'| | `-._`-._ _.-'_.-' | `-._ `-._`-.__.-'_.-' _.-' `-._ `-.__.-' _.-' `-._ _.-' `-.__.-' 7703:M 20 Aug 04:09:02.035 # WARNING: The TCP backlog setting of 1024 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128. #由于/proc/sys/net/core/somaxconn设置为较低的128,因此无法强制设置1024的TCP backlog。
7703:M 20 Aug 04:09:02.035 # Server initialized 7703:M 20 Aug 04:09:02.035 # WARNING overcommit_memory is set to 0! Background save may fail under low memory condition. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.
#警告提示3:overcommit_memory=0为不允许超额抢占内存,但是,rdb保存可能会失败。建议将vm.overcommit_memory = 1进行修改
7703:M 20 Aug 04:09:02.035 # WARNING you have Transparent Huge Pages (THP) support enabled in your kernel. This will create latency and memory usage issues with Redis. To fix this issue run the command 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' as root, and add it to your /etc/rc.local in order to retain the setting after a reboot. Redis must be restarted after THP is disabled.#警告提示4:你的内核中启用了巨大内存页的支持,这将与redis的延迟内存使用冲突。
7703:M 20 Aug 04:09:02.035 * Ready to accept connections
(1)调整系统文件描述符
echo "* - nofile 10240" >> /etc/security/limits.conf bash #刷新下即生效
ulimit -n
10240
(2)调整系统的TCP连接数
sysctl -a | grep soma sysctl: reading key "net.ipv6.conf.all.stable_secret" sysctl: reading key "net.ipv6.conf.default.stable_secret" sysctl: reading key "net.ipv6.conf.eth0.stable_secret" sysctl: reading key "net.ipv6.conf.lo.stable_secret" net.core.somaxconn = 128 echo "net.core.somaxconn = 10240" >> /etc/sysctl.conf sysctl -p net.core.somaxconn = 10240
(3)调整系统内存分配策略
echo "vm.overcommit_memory = 1" >> /etc/sysctl.conf sysctl -p net.core.somaxconn = 10240 vm.overcommit_memory = 1
vm.overcommit_memory参数说明:
根据内核文档,该参数有三个值,分别是:
0:当用户空间请求更多的内存时,内核尝试估算出剩余可用的内存。
1:当设这个参数值为1时,内核允许超量使用内存直到用完为止,主要用于科学计算
2:当设这个参数值为2时,内核会使用一个绝不过量使用内存的算法,即系统整个内存地址空间不能超过swap+50%的RAM值,50%参数的设定是在overcommit_ratio中设定。
(4)关闭系统内核的巨大内存页支持
echo never > /sys/kernel/mm/transparent_hugepage/enabled echo never > /sys/kernel/mm/transparent_hugepage/defrag #添加到/etc/rc.local echo 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' >> /etc/rc.local echo 'echo never > /sys/kernel/mm/transparent_hugepage/defrag' >> /etc/rc.local
(5)重启redis的服务器验证修改
redis-cli shutdown #关闭redis > /data/redis/redis.log #清空redis日志 redis-server /usr/local/redis/conf/redis.conf #启动redis
cat /data/redis/redis.log #查看redis日志 8064:C 20 Aug 04:22:42.049 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo 8064:C 20 Aug 04:22:42.050 # Redis version=4.0.10, bits=64, commit=00000000, modified=0, pid=8064, just started 8064:C 20 Aug 04:22:42.050 # Configuration loaded _._ _.-``__ ''-._ _.-`` `. `_. ''-._ Redis 4.0.10 (00000000/0) 64 bit .-`` .-```. ```/ _.,_ ''-._ ( ' , .-` | `, ) Running in standalone mode |`-._`-...-` __...-.``-._|'` _.-'| Port: 6379 | `-._ `._ / _.-' | PID: 8065 `-._ `-._ `-./ _.-' _.-' |`-._`-._ `-.__.-' _.-'_.-'| | `-._`-._ _.-'_.-' | http://redis.io `-._ `-._`-.__.-'_.-' _.-' |`-._`-._ `-.__.-' _.-'_.-'| | `-._`-._ _.-'_.-' | `-._ `-._`-.__.-'_.-' _.-' `-._ `-.__.-' _.-' `-._ _.-' `-.__.-' 8065:M 20 Aug 04:22:42.055 # Server initialized 8065:M 20 Aug 04:22:42.055 * DB loaded from disk: 0.000 seconds 8065:M 20 Aug 04:22:42.055 * Ready to accept connections
为php安装redis客户端扩展
(1)获取源码包
wget https://github.com/phpredis/phpredis/archive/2.2.4.tar.gz
(2)安装
unzip phpredis-master.zip #解压 cd /usr/src/phpredis-master/ /usr/local/php/bin/phpize
如果出现以下报错
Configuring for: PHP Api Version: 20090626 Zend Module Api No: 20090626 Zend Extension Api No: 220090626 Cannot find autoconf. Please check your autoconf installation and the $PHP_AUTOCONF environment variable. Then, rerun this script.
yum install m4 autoconf #安装这些解决 /usr/local/php/bin/phpize #再次执行 ./configure --with-php-config=/usr/local/php/bin/php-config #编译安装 make; make install
(3)修改php.ini设置,重启php
echo "extension = redis.so" >> /usr/local/php/lib/php.ini #将php.ini配置文件中的extension_dir修改成如下: extension_dir = "/usr/local/php/lib/php/extensions/no-debug-non-zts-20090626/"
安装Python redis客户端操作redis
wget https://pypi.python.org/packages/source/r/redis/redis-2.10.1.tar.gz tar xf redis-2.10.1.tar.gz cd redis-2.10.1 python setup.py install
开发python程序操作redis
python import redis #引用redis支持库 r = redis.Redis(host='192.168.50.157',port='6379',password='') #建立redis数据库的连接对象(面向对象方式) r.set('name','wk') #操作对象调用set方法写入数据 True r.get('name') #操作对象调用get方式读取数据 'wk'