一、Redis介绍
- Redis和Memcached类似,也属于k-v数据存储,但是功能和操作性要比Memcached好很多。
- Redis官网redis.io, 当前最新稳定版4.0.1 支持更多value类型,除了和string外,还支持hash、lists(链表)、sets(集合)和sorted sets(有序集合)
- redis使用了两种文件格式:全量数据(RDB)和增量请求(aof)。
- 全量数据格式是把内存中的数据写入磁盘,便于下次读取文件进行加载。
- 增量请求文件则是把内存中的数据序列化为操作请求,用于读取文件进行replay得到数据,这种类似于mysql binlog。为了节省资源,当我们手动保存一次全量数据,就可以删除当前的所有增量数据了,有些增量数据其实早就过期了,也可定期利用脚本做一些优化。
- redis的存储分为内存存储、磁盘存储和log文件三部分
- Redis最大的用户就是新浪微博,它的部署场景大致分为两种:
- 应用程序直接访问Redis数据库。
- 应用程序直接访问Redis,只有当Redis访问失败时,才访问Mysql。
Redis适用场景:
- 取出最新N个数据的操作
- 排行榜应用,取出Top N操作
- 需要精确设定过期时间的应用
- 计数器应用
- uniq操作,获取某段时间所有数据排除重复值
- 实时系统,反垃圾系统
- Pub/Sub构建实时消息系统。Redis独有功能,发布/订阅
- 构建队列系统
- 缓存
二、redis的安装与配置
[root@localhost ~]# cd /usr/local/src/
[root@localhost src]# wget http://download.redis.io/releases/redis-4.0.9.tar.gz
[root@localhost src]# tar zxvf redis-4.0.9.tar.gz
1.下面进行编译安装
2.对redis的文件进行拷贝到/etc/下面
[root@localhost redis-4.0.9]# vim /etc/redis.conf
以下为redis.conf配置内容的一些设置:
# Examples:
#
# bind 192.168.1.100 10.0.0.1 //此处配置监听IP
# bind 127.0.0.1 ::1
protected-mode yes //定义保护模式
# Accept connections on the specified port, default is 6379 (IANA #815344).
# If port 0 is specified Redis will not listen on a TCP socket.
port 6379 //监听端口
daemonize no //默认值为no,代表前台启动,yes表示后台启动
pidfile /var/run/redis_6379.pid //定义redis的PID
logfile "" //此处定义redis的log存放路径,默认为空
dir ./ //定义rdb的存放位置(aof也是存在这个位置),默认为根下
slave-priority 100 //此为设置权重,类似于负责均衡
appendonly no //只增文件的名称,默认为 no ,不指定
# The name of the append only file (default: "appendonly.aof")
appendfilename "appendonly.aof" //只增文件的名称为 appendonly.aof
# appendfsync always // 每次更新数据都写入仅增日志文件。慢,但是最安全。
appendfsync everysec //每秒调用一次。折中。(默认情况)
# appendfsync no ///不调用,等待操作系统来清空缓冲区当操作系统要输出数据时。很快。
大概了解以上设置含义,现在把配置文件中部分内容按下面设置;
[root@localhost ~]# vim /etc/redis.conf
daemonize yes //默认为no,现设置为yes
logfile "/var/log/redis.log" //默认为空
dir /data/redis //重新设置目录,原来为根下,等下需要创建定义的目录
appendonly yes //原为no
下面还要进行配置一些相关文件,之后就可以进行启动redis
启动redis的命令如下所示
查看日志的时候发现有警告的标识按照如下所示之后就没有警告
三、Redis 持久化
和Memcached服务一样,如果关闭RDB和aof数据就会存储在内存中,当重启服务或者重启机器 存储的数据就会丢失。如果数据很重要,我们就需要做持久化。
Redis的两种持久化方式:RDB(Redis DataBase)和AOF(Append Only File)。
RDB:在不同的时间点,将redis存储的数据生成快照并保存到磁盘等介质上。默认情况下,RDB是开启的。
AOF:将Redis执行过的所有指令记录下来,下次Redis重新启动时,只要把这些指令从前到后再重复执行一遍,就可以实现数据恢复了。默认情况,AOF是关闭的。
这两种方式可以同时使用。
如果你没有数据持久化的需求,就可以关闭RDB、AOF,这样就跟memcache一样,变成了一个纯内存数据库。
再次进入redis.conf配置文件
关闭持久化:把#去掉则关闭持久化
save "" //关闭持久化
#save 900 1 //表示每(900s)15分钟且至少有1个key改变,就触发一次持久化
#save 300 10 //表示每(300s)5分钟且至少有10个key改变,就触发一次持久化
#save 60 10000
AOF格式中appendfsync三种形式解析:
# appendfsync always //一直写,每次有变更就写进去
appendfsync everysec //安全高效,每一秒记录一次,把数据从内存刷新到磁盘中去
# appendfsync no //每隔一段时间,根据系统的算法,Linux系统不定期把内存的数据同步到磁盘上去,根据这个频率走,容易丢数据
开启AOF:appendonly yes,默认是appendonly no。
四、redis的数据类型
string为最简单的类型,与Memcached一样的类型,一个key对应一个value,其支持的操作与Memcached的操作类似,它的功能更丰富。设置可以存二进制的对象
设置多个键值对
4.2 Redis数据类型-list 链表
list是一个链表结构,主要功能是push、pop、获取一个范围的所有值等等。操作中key理解为链表的名字。
应用场景:
使用 list 结构,我们可以轻松地实现最新消息排行等功能(比如新浪微博的 TimeLine )。list 的另一个应用就是消息队列,可以利用 list 的 push操作,将任务存在 list 中,然后工作线程再用pop操作将任务取出进行执行。
4.3 Redis数据类型-set 集合
set是集合,和我们数学中的集合概念相似,对集合的操作有添加删除元素,有对多个集合求交并差等操作。操作中key理解为集合的名字。
应用场景:
比如在微博应用中,可以将一个用户所有的关注人存在一个集合中,将其所有粉丝存在一个集合。因为 Redis 非常人性化的为集合提供了求交集、并集、差集等操作,那么就可以非常方便的实现如共同关注、共同喜好、二度好友等功能,对上面的所有集合操作,你还可以使用不同的命令选择将结果返回给客户端还是存集到一个新的集合中
建立set1、set2集合元素
集合并集
集合交集
集合差集
删除元素
4.4 Redis数据类型-sort set 有序集合
sorted set是有序集合,它比set多了一个权重参数score,使得集合中的元素能够按 score 进行有序排列。
应用场景:
比如一个存储全班同学成绩的 Sorted Sets,其集合 value 可以是同学的学号,而 score 就可以是其考试得分,这样在数据插入集合的时候,就已经进行了天然的排序。
上面有第一个排序是正序第二个排序是倒序
4.5 Redis数据类型-hash
在 Memcached 中,我们经常将一些结构化的信息打包成 hashmap,在客户端序列化后存储为一个字符串的值(一般是 JSON 格式),比如用户的昵称、年龄、性别、积分等
五、Redis常用操作
5.1 string操作
- 如果一个key设置两个不同的值,第二个值会覆盖第一个值。
- SETNX 检测键值是否有value 如果有直接返回一个 0 如果没有直接返回一个 1 并且创建此 value
- setex 针对某个key设置一个过期时间
5.2、list操作
- LPUSH 取值,RPOP 或者 LPOP只要把值取出来 其中的值就会被删除掉。
lpush lista a //从左侧加入一个元素 lrange lista 0 -1 //取出从0开始到倒数第一个之间的元素 lpop lista //从左侧取出第一个元素 rpush lista 1 //从右侧加入一个元素 rpop lista //从右侧取出第一个元素
元素的修改:先在xxx清单增加 A B C D E ,然后更换第二位的数值
替换某个元素
5.3、set操作
前面已经演示过,下面set操作整理起来;
命令格式 | 释义 |
---|---|
sadd 集合名 元素 | 向集合添加元素 |
smembers 集合名 | 查看集合中的全部元素 |
srem 集合名 元素 | 删除元素 |
spop 集合名 | 取出一个元素,删除 |
sdiff 集合1 集合2 | 以集合1为标准,求差集 |
sdiffstore 集合1 集合2 集合3 | 求差集并储存到集合1 |
sinter 集合1 集合2 | 求交集 |
sinterstore 集合1 集合2 集合3 | 求交集,并存储到集合1 |
sunion 集合1 集合2 | 求并集 |
sunion 集合1 集合2 集合3 | 求并集并存储到集合1 |
sismembaer 集合 元素 | 判断一个元素是否属于一个集合,是则返回1。 |
srandmember 集合 | 取出一个元素,但不删除 |
zadd 集合 | 创建有序集合 |
zrange 集合 0 -1 | 显示所有元素,按顺序显示 |
zrange 集合 0 -1 withscores | 带上分值 |
zrem 集合 元素 | 删除指定元素 |
zrank 集合 元素 | 返回元素的索引值 |
zrevrank 集合 元素 | 按score反向排列 |
zrevrange 集合 0 -1 | 反向显示,并带分值 |
zcard 集合 | 返回集合中的元素的个数 |
zrangebyscore 集合 1 10 | 返回1-10的元素个数 |
zremrangebyrank 集合 0 2 | 删除索引0-2的元素,按分值正向排序 |
zremrangebyscore 集合 0 2 | 删除分值0-2的元素 |
5.3 hash操作
- HMSET 批量建立键值对
- 删除一个键
- HKEYS 打印所有的键值
- HVALS 打印所有的values
- hlen 查看有几个filed
六、Redis操作键值
常用以下键值
- keys * :取出所有键
- exists 键名:存在返回1
- del 键:删除键
- expire 键 100:设置键100秒后过期
- ttl 键:查看键的过期时间,单位是秒,当键不存在返回-2,键存在但没设置过期时间返回-1
- select 0 :代表选择当前数据库,默认进入0数据库
- move age 1 :把age移动到1数据库
- persist 键:取消键的过期时间
- randomkey:返回一个键
- rename oldname newname:重命名
- type 键:返回键的类型
判断键是否存在:
删除键
设置过期时间
查看过期时间
把某个键移动到其他库
取消键过期时间
键重新命名
键的类型:
dbsize:返回当前数据的key数量
七、Redis安全设置
如何解决redis漏洞
- 设置密码
- 更改默认端口
- 监听内网IP
- 设定专用账户
- 修改configure命令
修改配置文件并增加一个密码之后在重启redis服务
requirepass www123
如果在进入到redis里面可以直接进入不需要密码,但是当执行key *时就会出现报错的现象,所以要使用命令进行登录
还可以进行编辑文件对configure进行重命名之后进行重启redis服务
也可以禁止掉config命令就是把上面的命令aming处替换成空即可
八、redis慢查询日志
慢查询日志,两个参数:一个是执行时长,单位是微妙,另一个是慢查询日志的长度。当一个新的命令被写入日志时,最老的一条会从命令日志队列中被移除。
在配置文件redis.conf中,查看慢日志的定义
在配置文件redis.conf中,查看慢日志的定义:
[root@localhost ~]# vim /etc/redis.conf
slowlog-log-slower-than 1000:表示慢于1000ms则记录日志
slowlog-max-len 128:定义长度,最多存128条
使用命令行,查询慢日志
- slowlog get:列出 全部慢查询日志
- slowlog len:查看慢查询日志条数
九、php安装redis扩展模块
下载phpredis模块源码包,解压
[root@localhost]# cd /usr/local/src/
[root@localhost src]# wget https://codeload.github.com/phpredis/phpredis/zip/develop
[root@localhost src]# mv develop phpredis-develop.zip
[root@localhost src]# unzip phpredis-develop.zip
编译,安装php的redis模块
[root@localhost phpredis-develop]# cd phpredis-develop/
[root@localhost phpredis-develop]# /usr/local/php-fpm/bin/phpize
Configuring for:
PHP Api Version: 20131106
Zend Module Api No: 20131226
Zend Extension Api No: 220131226
[root@localhost phpredis-develop]# ./configure --with-php-config=/usr/local/php-fpm/bin/php-config
[root@localhost phpredis-develop]# make
[root@localhost phpredis-develop]# make install
在php.ini配置文件中添加 extension=redis.so
[root@localhost phpredis-develop]# vim /usr/local/php-fpm/etc/php.ini
extension=memcache.so //memcache模块之前添加的
extension=redis.so //添加
查看php-fpm模块中,是否有redis模块;
[root@localhost phpredis-develop]# /usr/local/php-fpm/bin/php -m|grep redis
redis
[root@localhost phpredis-develop]# /etc/init.d/php-fpm restart
Gracefully shutting down php-fpm . done
Starting php-fpm done
十、redis存储session
** redis存储session,有三种配置方法**:
1、/usr/local/php-fpm/etc/php.ini中添加:
session.save_handler = "redis"
session.save_path = "tcp://127.0.0.1:6379"
2、lamp中在Apache虚拟主机配置文件中添加:
php_value session.save_handler = "redis"
php_value session.save_path = "tcp://127.0.0.1:6379"
3、在php-fpm配置文件对应的pool:/usr/local/php-fpm/etc/php-fpm.d/ying.com.conf 中添加:
php_value[session.save_handler] = "redis"
php_value[session.save_path] = "tcp://127.0.0.1:6379"
把下面语句添加在 ying.com pool下
[root@localhost ~]# vim /usr/local/php-fpm/etc/php-fpm.d/ying.com.conf
添加以下语句:
php_value[session.save_handler] = redis
php_value[session.save_path] = " tcp://127.0.0.1:6379 "
在redis配置文件中,取消密码,方便试验
[root@localhost ~]# vim /etc/redis.conf
#requirepass www123 //加上#,就代表此命令不执行
更改配置文件后,需要重启redis服务
下面进行测试
[root@localhost ~]# curl localhost/1.php
1535202678<br><br>1535202678<br><br>fb0tk0r5nnvgs1fhngten6kvf4
[root@locaohost ~]# redis-cli
127.0.0.1:6379> keys *
1) "PHPREDIS_SESSION:d9u8oi1d0o1l2m6blm0gneb9p5"
十一、redis主从配置
在master(ying01)上修改redis的配置文件,master上改动不大
在master(ying01)上修改redis的配置文件,master上改动不大
[root@localhost ~]# vim /etc/redis.conf
bind 192.168.112.136 127.0.0.1
port 6379
pidfile /var/run/redis_6379.pid
appendonly yes
在slave(ying02)上修改redis的配置文件
[root@localhost ~]# vim /etc/redis.conf
bind 127.0.0.1 192.168.112.138
port 6380
pidfile /var/run/redis_6380.pid
slaveof 192.168.112.136 6379
appendonly yes
分别在master、slave机器上重启redis服务
[root@localhost ~]# killall redis-server
[root@localhost ~]# redis-server /etc/redis.conf
12.1 、redis集群介绍
先看redis的集群架构图
在这个图中,每一个蓝色的圈都代表着一个redis的服务器节点。它们任何两个节点之间都是相互连通的。客户端可以与任何一个节点相连接,然后就可以访问集群中的任何一个节点。对其进行存取和其他操作。
redis集群特点:
- 多个redis节点网络互联,数据共享
- 所有的节点都是一主一从(可以是多个从),其中从不提供服务,仅作为备用
- 不支持同时处理多个键(如mset/mget),因为redis需要把键均匀分布在各个节点上,并发量很高的情况下同时创建键值会降低性能并导致不可预测的行为。
- 支持在线增加、删除节点
- 客户端可以连任何一个主节点进行读写
参考资料:https://blog.csdn.net/yejingtao703/article/details/78484151
12.2 redis集群搭建配置
在01机器上
新建redis_7000.conf配置文件
[root@localhost ~]# cd /etc/
[root@localhost etc]# vim redis_7000.conf
port 7000
bind 192.168.126.128
daemonize yes
pidfile /var/run/redis_7000.pid
dir /data/redis_data/7000
cluster-enabled yes
cluster-config-file nodes_7000.conf
cluster-node-timeout 10100
appendonly yes
新建redis_7002.conf配置文件
[root@localhost etc]# vim redis_7002.conf
port 7002
bind 192.168.126.128
daemonize yes
pidfile /var/run/redis_7002.pid
dir /data/redis_data/7002
cluster-enabled yes
cluster-config-file nodes_7002.conf
cluster-node-timeout 10100
appendonly yes
新建redis_7004.conf配置文件
[root@localhost etc]# vim redis_7004.conf
port 7004
bind 192.168.126.128
daemonize yes
pidfile /var/run/redis_7004.pid
dir /data/redis_data/7004
cluster-enabled yes
cluster-config-file nodes_7004.conf
cluster-node-timeout 10100
appendonly yes
创建目录
[root@localhost etc]# mkdir /data/redis_data
[root@localhost etc]# mkdir /data/redis_data/{7000,7002,7004}
分别开启三个端口的服务
在02 机器上
新建redis_7001.conf配置文件
[root@localhost etc]# vim redis_7001.conf
port 7001
bind 192.168.126.129
daemonize yes
pidfile /var/run/redis_7001.pid
dir /data/redis_data/7001
cluster-enabled yes
cluster-config-file nodes_7001.conf
cluster-node-timeout 10100
appendonly yes
新建redis_7003.conf配置文件
[root@localhost etc]# vim redis_7003.conf
port 7003
bind 192.168.126.129
daemonize yes
pidfile /var/run/redis_7003.pid
dir /data/redis_data/7003
cluster-enabled yes
cluster-config-file nodes_7003.conf
cluster-node-timeout 10100
appendonly yes
新建redis_7005.conf配置文件
[root@localhost etc]# vim redis_7005.conf
port 7005
bind 192.168.126.129
daemonize yes
pidfile /var/run/redis_7005.pid
dir /data/redis_data/7005
cluster-enabled yes
cluster-config-file nodes_7005.conf
cluster-node-timeout 10100
appendonly yes
创建目录
[root@localhost etc]# mkdir /data/redis_data
[root@localhost etc]# mkdir /data/redis_data/{7001,7003,7005}
分别开启7001、7003、7005的redis服务
在01机器上安装ruby2.2(只需要在01上安装)
[root@localhost ~]# yum -y groupinstall "Development Tools"
[root@localhost ~]# yum -y install gdbm-devel libdb4-devel libffi-devel libyaml libyaml-devel ncurses-devel openssl-devel readline-devel tcl-deve
创建rpmbuild目录及其子目录
[root@localhost ~]# mkdir -p rpmbuild/{BUILD,BUILDROOT,RPMS,SOURCES,SPECS,SRPMS}
[root@localhost ~]# ls rpmbuild/
BUILD BUILDROOT RPMS SOURCES SPECS SRPMS
下载ruby的源码包,存放在rpmbuild/SOURCES目录下
[root@localhost ~]# wget http://cache.ruby-lang.org/pub/ruby/2.2/ruby-2.2.3.tar.gz -P rpmbuild/SOURCES
下载ruby的spec的文件,目的rpmbuild把其生成rpm文件
[root@localhost ~]# wget https://raw.githubusercontent.com/tjinjin/automate-ruby-rpm/master/ruby22x.spec -P rpmbuild/SPECS
[root@localhost ~]# rpmbuild -bb rpmbuild/SPECS/ruby22x.spec
安装 ruby-2.2.3-1.el7.centos.x86_64.rpm ,并查看其版本号
[root@localhost ~]# ls rpmbuild/RPMS/x86_64/ruby-2.2.3-1.el7.centos.x86_64.rpm
rpmbuild/RPMS/x86_64/ruby-2.2.3-1.el7.centos.x86_64.rpm
[root@localhost ~]# du -sh !$
du -sh rpmbuild/RPMS/x86_64/ruby-2.2.3-1.el7.centos.x86_64.rpm
10M rpmbuild/RPMS/x86_64/ruby-2.2.3-1.el7.centos.x86_64.rpm
[root@localhost ~]# rpm -ivh rpmbuild/RPMS/x86_64/ruby-2.2.3-1.el7.centos.x86_64.rpm
准备中... ################################# [100%]
正在升级/安装...
1:ruby-2.2.3-1.el7.centos ################################# [100%]
[root@localhost ~]# ruby -v //查看版本号
ruby 2.2.3p173 (2015-08-18 revision 51636) [x86_64-linux]
用gem安与redis中与ruby相关的文件 redis-trib.rb
[root@localhost ~]# gem install redis
Fetching: redis-4.0.2.gem (100%)
Successfully installed redis-4.0.2
Parsing documentation for redis-4.0.2
Installing ri documentation for redis-4.0.2
Done installing documentation for redis after 1 seconds
1 gem installed
现在把redis-trib.rb 复制到/usr/bin/下,可以直接使用这个命令
[root@localhost ~]# cp /usr/local/src/redis-4.0.9/src/redis-trib.rb /usr/bin/
用redis-trib.rb 命令分配主、从端口
[root@localhost ~]# redis-trib.rb create --replicas 1 192.168.126.128:7000 192.168.126.128:7002 192.168.126.128:7004 192.168.126.129:7001 192.168.126.129:7003 192.168.126.129:7005
12.3 、redis集群操作
开始以集群的方式登录,创建不同的值,观察存在哪个服务器(端口)
[root@localhost ~]# redis-cli -c -h 192.168.126.128 -p 7000 //-c 表示以集群的方式登录,否则就是单机登录
检测集群状态 redis-trib.rb IP:port
[root@localhost ~]# redis-trib.rb check 192.168.126.128:7000 //可以跟任何端口
以集群的方式登录到redis下,一些重用操作:
- 列出节点 cluster nodes
- 查看集群的信息 cluster info
- 添加节点 cluster meet ip port
在02机器上,新建一个7007的配置文件
[root@localhost etc]# vim redis_7007.conf
port 7007
bind 192.168.126.129
daemonize yes
pidfile /var/run/redis_7007.pid
dir /data/redis_data/7007
cluster-enabled yes
cluster-config-file nodes_7007.conf
cluster-node-timeout 10100
appendonly yes
创建目录,并启动
[root@localhost etc]# mkdir /data/redis_data/7007
[root@localhost etc]# redis-server /etc/redis_7007.conf
回到01上进行添加节点
- 将当前节点设置为指定节点的从: cluster replicate node_id
[root@localhost etc]# redis-cli -c -h 192.168.126.128 -p 7006 //以7006端口登录到集群
- 移除某个节点:cluster forget node_id
不能移走master,也不能移走当前节点的
- 保存配置文件: cluster saveconfig