目录
4、server3下载解压gearman,并解决依赖性进行编译
Redis简介
Redis 是完全开源的,遵守 BSD 协议,是一个高性能的 key-value 数据库。
特点
1.Redis支持数据的持久化,可以将内存中的数据保存在磁盘中,重启的时候可以再次加载进行使用。
2.Redis不仅仅支持简单的key-value类型的数据,同时还提供list,set,zset,hash等数据结构的存储。
3.Redis支持数据的备份,即master-slave模式的数据备份。
redis的编译、安装
https://redis.io/download
tar zxf redis-5.0.8.tar.gz
make && make install
utils/install_server.sh
1、server1的redis配置
server1主机,安装并编译redis。
运行自带的安装程序,安装失败,文件中有操作系统的判断会导致失败,修改文件,重新安装
cd utils/
ls
./install_server.sh ##运行自带的安装程序,失败
vim install_server.sh ##将下文部分注释,重新运行自带的安装程序
出现提示直接回车即可
如果要 再次安装 在提示时输入 以存在6379的后一位6380即可:
此时切换到配置目录下,可以看到自动生成了配置文件,查看端口,端口开启。修改该配置文件,重启服务。
cd /etc/redis
ls ##6379.conf
netstat -antlp ##6379
vim 6379.conf
///
75 #bind 127.0.0.1 -::1 ##链接redis 时只能通过本地localhost (127.0.0.1)来链接,而不能用网络ip(192.168..)链接,因为处于保护模式,只能本地链接,所以将该设定注释
94 protected-mode no ##设定关闭保护模式
///
/etc/init.d/redis_6379 stop
/etc/init.d/redis_6379 start
netstat -antlp | grep :6379
2、server2的redis安装
在server2主机,使用另一种方式来配置redis。
首先,同样先解压,然后使用systemd支持进行构建,但此时缺少依赖gcc,安装依赖,重新make,仍然失败,提醒缺少依赖jemalloc。此时要删除redis目录,删除c环境下生成的缓存,重新解压,make,提醒缺少systemd,安装后继续make,成功,make install
scp -r redis-6.2.4.tar.gz server2: #server1直接将解压好的mulu 传输给server2
因为redis是c语言开发的,所以需要下载gcc进行安装编译
yum install -y gcc #下载gcc
yum install -y systemd-devel
vim README.md #查看使用手册,可以发现如果服务需要用刀systemd,make时需要添加参数USE_SYSTEMD=yes
make USE_SYSTEMD=yes #redis使用systemd守护进程
make install #安装
切换到utils目录下,运行自带的安装程序,将服务文件复制到目录自动存放启动文件的配置位置,重载配置文件,重启服务。
cd utils/
./install_server.sh
cp systemd-redis_server.service /usr/lib/systemd/system/redis.service ##目录自动存放启动文件的配置位置
systemctl daemon-reload ##重载配置文件
systemctl start redis.service
3、server3配置redis
server3的redis配置和server1相同
三、redis主从复制
1、在server2修改redis.service文件,建立配置文件和数据文件存放的目录,编辑配置文件,同时设定server2主机为server1主机的slave端,即主从复制设定,重载配置文件,重启服务。
cd /usr/lib/systemd/system/
vim redis.service
mkdir /etc/redis
mkdir /var/lib/redis
cd
cd redis-6.2.4/
cp redis.conf /etc/redis/
vim /etc/redis/redis.conf
///
94 protected-mode no ##关闭保护模式
75 #bind 127.0.0.1 -::1 ##注释,允许网络ip链接redis
257 daemonize yes ##以守护进程的方式运行
302 logfile "/var/log/redis.log" ##日志存放目录
454 dir /var/lib/redis ##数据文件放置的目录
2052 slaveof 172.25.35.16379 ##主从复制
///
systemctl daemon-reload
systemctl restart redis
2、此时在server1主机上插入数据,可以在server2和server3主机上看到,即主从复制设定成功。
3、进入redis,info可以看到redis的从属关系
四、Sentine主从自动切换
使用哨兵模式,自动监视Master节点,当前挂掉后,自动将Slaver节点变为Master节点
环境:当前server1为master,server2、3为slave
配置哨兵模式,即高可用
###server1
cd redis-6.2.4/
cp sentinel.conf /etc/redis/
cd /etc/redis/
vim sentinel.conf
///
sentinel monitor mymaster 172.25.35.1 6379 2 ##master为server1,2表示需要两票通过,这台主机就被认定宕掉
sentinel down-after-milliseconds mymaster 10000 ##连接超时为10s
///
scp sentinel.conf server2:/etc/redis/
scp sentinel.conf server3:/etc/redis/
redis-sentinel /etc/redis/sentinel.conf ##可以看到两个slave端
在server1中关闭redis ,查看变化,会显示已关闭及server2、server3的竞选master的过程
redis-cli --> info --> SHUTDDOWN
此时,server3变为了master(也可能是server2,因为是两个slave选出来的master,所以不同的环境可能选出的master不同)
连接 server3 的 redis 查看状态,显示server3为master、server2为slave、server1关闭不显示
现在server1是关闭的,开启server1的redis后,server1会自动切换为slave,并清空之前的所有数据
五、redis的集群cluster
Redis集群总结
1.Redis集群是一个由多个节点组成的分布式服务集群,它具有复制、高可用和分片特性
2.Redis的集群没有中心节点,并且带有复制和故障转移特性,这可用避免单个节点成为性能瓶颈,或者因为某个节点下线而导致整个集群下线
3.集群中的主节点负责处理槽(储存数据),而从节点则是主节点的复制品
4.Redis集群将整个数据库分为16384个槽,数据库中的每个键都属于16384个槽中的其中一个
5.集群中的每个主节点都可以负责0个至16384个槽,当16384个槽都有节点在负责时,集群进入上线状态,可以执行客户端发送的数据命令
6.主节点只会执行和自己负责的槽有关的命令,当节点接收到不属于自己处理的槽的命令时,它将会处理指定槽的节点的地址返回给客户端,而客户端会向正确的节点重新发送
7.如果需要完整地分片、复制和高可用特性,并且要避免使用代理带来的性能瓶颈和资源消耗,那么可以选择使用Redis集群;
如果只需要一部分特性(比如只需要分片,但不需要复制和高可用等),那么单独选用twemproxy、Redis的复制和Redis Sentinel中的一个或多个
1.集群构建
手动构建集群
server1主机为master,重启redis,开启AOF模式,建立medis目录,及集群7001~7006目录,分别配置目录下配置文件,启动服务
/etc/init.d/redis_6379 restart
vim /etc/redis/6379.conf
\\\
appendonly yes ##开启AOF模式
\\\
cd /usr/local
mkdir redis #创建目录
cd redis/
mkdir 700{1..6} #创建六个节点的目录
cd 7001
vim redis.conf #编辑配置文件
///
port 7001
cluster-enabled yes ##开启集群
cluster-config-file nodes.conf ##集群配置文件
cluster-node-timeout 5000 ##节点超时
appendonly yes ##开启AOF模式
daemonize yes ##用守护线程的方式启动
///
redis-server redis.conf ##启动服务
ps ax ##redis-server *:7001 [cluster]
cp redis.conf ../7002/ ##复制配置文件到7002-7006
cp redis.conf ../7003/
cp redis.conf ../7004/
cp redis.conf ../7005/
cp redis.conf ../7006/
再分别进入各节点目录中修改配置文件中——port 7001
例如:
cd 7002/
vim redis.conf
///
port 7002
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes
daemonize yes
///
redis-server redis.conf #启动服务
server1为master
##开启AOF模式
创建redis目录后,在各节点目录中编辑配置文件 redis.conf (7001目录中的文件)
最终可以使用ps查看,此时所有节点的服务都已经启动
创建集群主从节点,–cluster-replicas 参数为数字,1表示每个主节点需要1个从节点。然后检查集群,查看集群信息。
redis-cli --cluster create 127.0.0.1:7001 127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005 127.0.0.1:7006 --cluster-replicas 1 #创建集群
redis-cli --cluster check 127.0.0.1:7001 ##检查集群
redis-cli --cluster info 127.0.0.1:7001 ##集群信息查看
创建六个节点,1、2、3为master,一主一从
集群信息查看 (这里观察 key 可以看到master和slave一一对应)
脚本构建集群
cd
cd redis-6.2.4/
cd utils/create-cluster/
./create-cluster start ##开启实例Starting 30001~30006
ps ax
./create-cluster stop ##停止所有实例,使用手动构建的集群来做接下来的实验,以防混乱
ps ax #查看
2.节点主从自动切换
之前查看节点信息我们直到节点主从信息,如下:master2对应slave5
当master2:7002关掉,7005会自动切换成主节点 ,此时没有从节点,重新打开7002,发现7002变为了7005的从节点
3.添加节点和分片
创建7007、7008两个节点的目录及配置文件
mkdir 700{7,8}
cd 7007
cp ../7001/redis.conf .
vim redis.conf
///
port 7007
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes
daemonize yes
///
redis-server redis.conf
7008相同
ps ax
开启7007, 将7007节点加入集群中,但是并没有分配slot,所以这个节点并没有真正的开始分担集群工作,所以要进行分片。重新分片基本上意味着将哈希槽从一组节点移动到另一组节点,并且像群集创建一样。
7007节点为master
分配slot
redis-cli --cluster reshard 127.0.0.1:7001 #重新分片
分片操作
How many slots do you want to move (from 1 to 16384)? 1000 #移动的插槽数量
What is the receiving node ##7007节点的ID(接收节点的ID)
Source node #1: all #从哪些节点获取这些密钥,输入all则从所有其他主节点获取这些哈希槽
Do you want to proceed with the proposed reshard plan (yes/no)? yes #确定是否要继续重新分片,输入yes
redis-cli --cluster check 127.0.0.1:7001 #检查集群信息
此时7007节点有1000哈希槽,没有从节点
开启7008,把7008 节点加入到7001 节点的集群中 ,当做7007的从节点。如果不指定 --cluster-master-id 会随机分配到任意一个主节点。
查看集群, 此时7007有一个从节点
六、Redis+Mysql读写分离
实际的生产环境当中,客户端对数据库的读操作都是直接找redis拿数据的
如果redis缓存里面没有数据,那么就会去找mysql拿数据,并且给redis中缓存一份
redis中的数据有两种情况不能使用:数据过期了或者mysql中的数据更新了 用户读的时候访问redis,用户写的时候访问mysql
实际上读的需求量是很大的,redis刚好是把数据缓存在内存当中,响应速度也快 也可以降低我们后台mysql数据库的压力
一般对于高并发的系统来说,搭建一个健壮的缓存系统是不可避免的。
单机的reids的QPS可能只能上万,如果有再高并发的场景,单机是不能搞定的,就会有它的系统瓶颈。
一般来说缓存是用来支撑高并发读,这时候我们可能就会想到读写分离; 读写分离是用来处理读的并发量大,而写的并发量小的场景。
在server1主机中(nginx+php)
接着上一个实验,我们需要杀死所有的redis进程,方便起见我们需要安装进程管理工具,便于使用killall命令,关掉之前redis所有进程
yum install -y psmisc ##便于使用killall命令
killall redis-server
ps ax ##没有redis且nginx和php正常
安装软件包php、gearmand、libevent-devel、libgearman相关软件包
本地主机获取软件包
lftp 172.25.254.250
cd /pub/docs/redis
mirror rhel7/
exit
cd rhel7/
yum install -y *.rpm #全部安装
systemctl daemon-reload
systemctl start php-fpm #开启php
修改测试页test.php内容,修改主从ip
mv test.php /usr/local/nginx/html/
vim test.php
///
3 $redis->connect('172.25.35.2',6379)
10 $connect = mysql_connect('172.25.35.3','redis','westos');
///
在server2主机中(redis)
开启redis,info查看信息,当前为server1的从机。修改配置文件/etc/redis/redis.conf,删除关于主从的设定,重启redis。info查看server2此时为master主机
在server3主机中(mariadb数据库)
停掉redis,并且取消开机自启。删除redis环境变量并且生效
/etc/init.d/redis_6379 stop
chkconfig redis_6379 off ##取消开机自启
vim .bash_profile
///
PATH=$PATH:$HOME/bin
///
source .bash_profile
在server3主机中(mariadb数据库)
停掉rdis,并且取消开机自启。删除redis环境变量并且生效,安装mariadb 还原mysql的配置文件,删除mysql所有数据文件,开启mariadb
/etc/init.d/redis_6379 stop
chkconfig redis_6379 off ##取消开机自启
vim .bash_profile
///
PATH=$PATH:$HOME/bin
///
source .bash_profile
yum install -y mariadb-server.x86_64
vim /etc/my.cnf
///
[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
[mysqld_safe]
log-error=/var/lib/mysql/mysqld.log
pid-file=/var/lib/mysql/mysqld.pid
///
systemctl start mariadb
进入数据库,可以看到test库,将本地文件test.sql文件导入,进入数据库,可以看到导入的数据,并授权redis用户
mysql
show databases;
mysql < test.sql #将test库内容导入
mysql
> use test
> show tables;
> select * from test; ##test1~test9
> grant all on test.* to redis@'%' identified by 'westos'; #授权
systemctl restart mariadb.service
在浏览器访问172.25.173.5/test.php
此数据只能同步复制,不能异步复制,只能在redis上改写和读取数据,mysql端更改不生效,即数据不一致,因为客户端读的时候去找redis缓存;客户端写的时候去找mysql
在server2中
redis-cli
--> get 1
"test1"
--> SET 1 westos
ok
...
七、redis与mysql保持数据一致
1、Gearman简介
Gearman提供了一个通用的应用程序框架,用于将工作转移到更适合于工作的其他机器或流程。它允许你并行工作,负载平衡处理,并在语言间调用函数。它可用于从高可用性网站到传输数据库复制事件的各种应用程序
2、在server3安装数据库的开发包
安装数据库的开发包,通过 lib_mysqludf_json UDF 库函数将关系数据映射为 JSON 格式,拷贝 lib_mysqludf_json.so 模块。进入数据库,查看mysql 的模块目录,注册 UDF 函数,查看函数
yum install -y unzip
unzip lib_mysqludf_json-master.zip
cd lib_mysqludf_json-master/
yum install -y gcc
gcc $(mysql_config --cflags) -shared -fPIC -o lib_mysqludf_json.so lib_mysqludf_json.c
cp lib_mysqludf_json.so /usr/lib64/mysql/plugin/
进入mysql查看
mysql
mysql> show global variables like 'plugin_dir';
3、注册UDF函数
mysql> CREATE FUNCTION json_object RETURNS STRING SONAME 'lib_mysqludf_json.so';
mysql> select * from mysql.func;
4、server3下载解压gearman,并解决依赖性进行编译
tar zxf gearman-mysql-udf-0.6.tar.gz
cd gearman-mysql-udf-0.6/
./configure --libdir=/usr/lib64/mysql/plugin/
server1主机上的rhel7包中含有以下rpm安装包
yum install -y libgearman* libevent*
#libevent-devel-2.0.21-4.el7.x86_64.rpm
#libgearman-1.1.12-18.el7.x86_64.rpm
#libgearman-devel-1.1.12-18.el7.x86_64.rpm
./configure --libdir=/usr/lib64/mysql/plugin/ 再次检测
make 编译
make install 安装
注册UDF函数,并查看
mysql
mysql> CREATE FUNCTION gman_do_background RETURNS STRING SONAME 'libgearman_mysql_udf.so';
mysql> CREATE FUNCTION gman_servers_set RETURNS STRING SONAME 'libgearman_mysql_udf.so';
mysql> select * from mysql.func;
SELECT gman_servers_set('172.25.173.5:4730'); 指定gearman的服务信息
5、编辑mysql触发器,重新导入数据库
vim test.sql ##编写 mysql 触发器
mysql -pwestos < test.sql
mysql
> SHOW TRIGGERS FROM test; ##查看触发器
6、在server1中启动服务及worker任务
systemctl start gearmand ##启动gearman服务
php -m | grep gearman #查看服务
php -m | grep redis
netstat -antlp #查看4370端口是否开启
cd /root/rhel7/ #切换环境到worker.php目录中
vim worker.php #编写 gearman 的 worker 端
///
7 $redis->connect('172.25.35.2', 6379);
///
cp worker.php /usr/local
cd /usr/local
nohup php worker.php & #运行worker.php并打入后台
ps ax #查看是否开启 worker.php
server1中的服务启动完毕,到mariadb中更改数据,server2中redis检查是否同步,浏览器查看。