主从server1 server2 server
3都安装
[root@server1 ~]# yum install -y gcc
[root@server1 ~]# tar zxf redis-4.0.8.tar.gz
[root@server1 ~]# cd redis-4.0.8
[root@server1 redis-4.0.8]# make
[root@server1 redis-4.0.8]# make install
默认安装路径
[root@server1 redis-4.0.8]# which redis-cli
/usr/local/bin/redis-cli
[root@server1 redis-4.0.8]# cd utils/
[root@server1 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/bin/redis-server]
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.
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@server1 utils]# redis-cli
127.0.0.1:6379> info
[root@server1 utils]# netstat -antlp
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 127.0.0.1:6379 0.0.0.0:* LISTEN 6236/redis-server 1
[root@server1 utils]# vim /etc/redis/6379.conf
[root@server1 utils]# /etc/init.d/redis_6379 stop
Stopping ...
Redis stopped
[root@server1 utils]# /etc/init.d/redis_6379 start
Starting Redis server...
[root@server1 redis-4.0.8]# redis-cli
127.0.0.1:6379> set name haha
OK
127.0.0.1:6379> get name
"haha"
127.0.0.1:6379> set user1 123
OK
127.0.0.1:6379> get user1
"123"
127.0.0.1:6379> del user1
(integer) 1
127.0.0.1:6379> get user1
(nil)
Server2 server3
Server2,3更改配置文件
[root@server2 redis-4.0.8]# vim /etc/redis/6379.conf
bind 0.0.0.0
# slaveof <masterip> <masterport>
slaveof 172.25.53.3 6379
就可以与master同步了
Server1
[root@server1 redis-4.0.8]# ls
00-RELEASENOTES COPYING Makefile redis.conf runtest-sentinel tests
BUGS deps MANIFESTO runtest sentinel.conf utils
CONTRIBUTING INSTALL README.md runtest-cluster src
[root@server1 redis-4.0.8]# cp sentinel.conf /etc/redis/
[root@server1 redis-4.0.8]# cd /etc/redis/
[root@server1 redis]# ls
6379.conf sentinel.conf
[root@server1 redis]# vim sentinel.conf
一定要在重启之前传给2,3
[root@server1 redis]# scp sentinel.conf server2:/etc/redis/
sentinel.conf 100% 7590 7.4KB/s 00:00
[root@server1 redis]# scp sentinel.conf server3:/etc/redis/
sentinel.conf 100% 7590 7.4KB/s 00:00
查看
[root@server1 redis]# redis-server /etc/redis/sentinel.conf --sentinel
6289:X 11 Aug 17:15:25.166 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
6289:X 11 Aug 17:15:25.166 # Redis version=4.0.8, bits=64, commit=00000000, modified=0, pid=6289, just started
6289:X 11 Aug 17:15:25.166 # Configuration loaded
6289:X 11 Aug 17:15:25.169 * Increased maximum number of open files to 10032 (it was originally set to 1024).
_._
_.-``__ ''-._
_.-`` `. `_. ''-._ Redis 4.0.8 (00000000/0) 64 bit
.-`` .-```. ```\/ _.,_ ''-._
( ' , .-` | `, ) Running in sentinel mode
|`-._`-...-` __...-.``-._|'` _.-'| Port: 26379
| `-._ `._ / _.-' | PID: 6289
`-._ `-._ `-./ _.-' _.-'
|`-._`-._ `-.__.-' _.-'_.-'|
| `-._`-._ _.-'_.-' | http://redis.io
`-._ `-._`-.__.-'_.-' _.-'
|`-._`-._ `-.__.-' _.-'_.-'|
| `-._`-._ _.-'_.-' |
`-._ `-._`-.__.-'_.-' _.-'
`-._ `-.__.-' _.-'
`-._ _.-'
`-.__.-'
6289:X 11 Aug 17:15:25.173 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
6289:X 11 Aug 17:15:25.565 # Sentinel ID is e1d128c43d6b3f32d11f21c34d0c13a9579d00b4
6289:X 11 Aug 17:15:25.565 # +monitor master mymaster 172.25.53.1 6379 quorum 2
6289:X 11 Aug 17:15:25.569 * +slave slave 172.25.53.2:6379 172.25.53.2 6379 @ mymaster 172.25.53.1 6379
6289:X 11 Aug 17:15:25.608 * +slave slave 172.25.53.3:6379 172.25.53.3 6379 @ mymaster 172.25.53.1 6379
Server2查看
我们将现在的master(server1)停掉
再打开
Redis集群介绍
Redis 集群是一个提供在多个Redis间节点间共享数据的程序集。
Redis集群并不支持处理多个keys的命令,因为这需要在不同的节点间移动数据,从而达不到像Redis那样的性能,在高负载的情况下可能会导致不可预料的错误.
Redis 集群通过分区来提供一定程度的可用性,在实际环境中当某个节点宕机或者不可达的情况下继续处理命令. Redis 集群的优势:
自动分割数据到不同的节点上。
整个集群的部分节点失败或者不可达的情况下能够继续处理命令。
Redis 集群的数据分片
Redis 集群没有使用一致性hash, 而是引入了 哈希槽的概念.
Redis 集群有16384个哈希槽,每个key通过CRC16校验后对16384取模来决定放置哪个槽.集群的每个节点负责一部分hash槽,举个例子,比如当前集群有3个节点,那么:
节点 A 包含 0 到 5500号哈希槽.
节点 B 包含5501 到 11000 号哈希槽.
节点 C 包含11001 到 16384号哈希槽.
这种结构很容易添加或者删除节点. 比如如果我想新添加个节点D, 我需要从节点 A, B, C中得部分槽到D上. 如果我想移除节点A,需要将A中的槽移到B和C节点上,然后将没有任何槽的A节点从集群中移除即可. 由于从一个节点将哈希槽移动到另一个节点并不会停止服务,所以无论添加删除或者改变某个节点的哈希槽的数量都不会造成集群不可用的状态.
Redis 集群的主从复制模型
为了使在部分节点失败或者大部分节点无法通信的情况下集群仍然可用,所以集群使用了主从复制模型,每个节点都会有N-1个复制品.
在我们例子中具有A,B,C三个节点的集群,在没有复制模型的情况下,如果节点B失败了,那么整个集群就会以为缺少5501-11000这个范围的槽而不可用.
然而如果在集群创建的时候(或者过一段时间)我们为每个节点添加一个从节点A1,B1,C1,那么整个集群便有三个master节点和三个slave节点组成,这样在节点B失败后,集群便会选举B1为新的主节点继续服务,整个集群便不会因为槽找不到而不可用了
不过当B和B1 都失败后,集群是不可用的.
Redis 一致性保证
Redis 并不能保证数据的强一致性. 这意味这在实际中集群在特定的条件下可能会丢失写操作.
第一个原因是因为集群是用了异步复制. 写操作过程:
客户端向主节点B写入一条命令.
主节点B向客户端回复命令状态.
主节点将写操作复制给他得从节点 B1, B2 和 B3.
主节点对命令的复制工作发生在返回命令回复之后, 因为如果每次处理命令请求都需要等待复制操作完成的话, 那么主节点处理命令请求的速度将极大地降低 —— 我们必须在性能和一致性之间做出权衡。 注意:Redis 集群可能会在将来提供同步写的方法。 Redis 集群另外一种可能会丢失命令的情况是集群出现了网络分区, 并且一个客户端与至少包括一个主节点在内的少数实例被孤立。
举个例子 假设集群包含 A 、 B 、 C 、 A1 、 B1 、 C1 六个节点, 其中 A 、B 、C 为主节点, A1 、B1 、C1 为A,B,C的从节点, 还有一个客户端 Z1 假设集群中发生网络分区,那么集群可能会分为两方,大部分的一方包含节点 A 、C 、A1 、B1 和 C1 ,小部分的一方则包含节点 B 和客户端 Z1 .
Z1仍然能够向主节点B中写入, 如果网络分区发生时间较短,那么集群将会继续正常运作,如果分区的时间足够让大部分的一方将B1选举为新的master,那么Z1写入B中得数据便丢失了.
注意, 在网络分裂出现期间, 客户端 Z1 可以向主节点 B 发送写命令的最大时间是有限制的, 这一时间限制称为节点超时时间(node timeout), 是 Redis 集群的一个重要的配置选项:
搭建并使用Redis集群
搭建集群的第一件事情我们需要一些运行在 集群模式的Redis实例. 这意味这集群并不是由一些普通的Redis实例组成的,集群模式需要通过配置启用,开启集群模式后的Redis实例便可以使用集群特有的命令和特性了
[root@server1 ~]# cd /usr/local/
[root@server1 local]# ls
bin etc games include lib lib64 libexec sbin share src
[root@server1 local]# mkdir cluster
[root@server1 local]# cd cluster/
[root@server1 cluster]# mkdir 7001
[root@server1 cluster]# mkdir 7002
[root@server1 cluster]# mkdir 7003
[root@server1 cluster]# mkdir 7004
[root@server1 cluster]# mkdir 7005
[root@server1 cluster]# mkdir 7006
[root@server1 7001]# vim redis.conf
下面是一个最少选项的集群的配置文件:
port 7001
cluster-enabled yes
cluster-config-file nodes.comf
cluster-node-timeout 5000
appendonly yes
文件中的 cluster-enabled 选项用于开实例的集群模式, 而 cluster-conf-file 选项则设定了保存节点配置文件的路径, 默认值为 nodes.conf.节点配置文件无须人为修改, 它由 Redis 集群在启动时创建, 并在有需要时自动进行更新。
要让集群正常运作至少需要三个主节点,不过在刚开始试用集群功能时, 强烈建议使用六个节点: 其中三个为主节点, 而其余三个则是各个主节点的从节点。
[root@server1 7001]# cd
[root@server1 ~]# cd redis-4.0.8
[root@server1 redis-4.0.8]# cd src/
[root@server1 src]# cp redis-trib.rb /usr/local/bin/
[root@server1 src]# cd /usr/local/bin/
[root@server1 bin]# ls
redis-benchmark redis-check-rdb redis-sentinel redis-trib.rb
redis-check-aof redis-cli redis-server
[root@server1 bin]# cd
[root@server1 ~]# yum install -y ruby
[root@server1 ~]# yum install rubygems-1.3.7-5.el6.noarch.rpm
[root@server1 ~]# yum install ruby-2.2.3-1.el6.x86_64.rpm libyaml-0.1.3-4.el6_6.x86_64.rpm
[root@server1 ~]# gem install --local redis-4.0.1.gem
Successfully installed redis-4.0.1
Parsing documentation for redis-4.0.1
Installing ri documentation for redis-4.0.1
Done installing documentation for redis after 1 seconds
1 gem installed
[root@server1 ~]# gem install --local redis-4.0.1.gem
[root@server1 ~]# gem list --local
[root@server1 ~]# cd /usr/local/cluster/
[root@server1 cluster]# ls
7001 7002 7003 7004 7005 7006
[root@server1 cluster]# cd 7001/
[root@server1 7001]# ls
redis.conf
[root@server1 7001]# vim redis.conf
[root@server1 7001]# cat redis.conf
port 7001
cluster-enabled yes
cluster-config-file nodes.comf
cluster-node-timeout 5000
appendonly yes
daemonize yes
pidfile /usr/local/cluster/7001/redis.pid
logfile /usr/local/cluster/7001/redis.log
[root@server1 7001]# ls
redis.conf
[root@server1 7001]# redis-server redis.conf
[root@server1 7001]# ls
appendonly.aof nodes.comf redis.conf redis.log redis.pid
[root@server1 cluster]# cd 7002
[root@server1 7002]# vim redis.conf
将7001更改为自己(7002),后面的7003-7006操作与2相同
[root@server1 7002]# redis-server redis.conf
添加集群
[root@server1 7006]#
搭建集群
现在我们已经有了六个正在运行中的 Redis 实例, 接下来我们需要使用这些实例来创建集群, 并为每个节点编写配置文件。
通过使用 Redis 集群命令行工具 redis-trib , 编写节点配置文件的工作可以非常容易地完成: redis-trib 位于 Redis 源码的 src 文件夹中, 它是一个 Ruby 程序, 这个程序通过向实例发送特殊命令来完成创建新集群, 检查集群, 或者对集群进行重新分片(reshared)等工作
[root@server1 7006]# redis-trib.rb create --replicas 1 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
这个命令在这里用于创建一个新的集群, 选项–replicas 1 表示我们希望为集群中的每个主节点创建一个从节点。
之后跟着的其他参数则是这个集群实例的地址列表,3个master3个slave redis-trib 会打印出一份预想中的配置给你看, 如果你觉得没问题的话, 就可以输入 yes , redis-trib 就会将这份配置应用到集群当中,让各个节点开始互相通讯,
[OK] All 16384 slots covered.
这表示集群中的 16384 个槽都有至少一个主节点在处理, 集群运作正常。
Check查看
[root@server1 7006]# redis-cli -c -p 7001
127.0.0.1:7001> set name haha
-> Redirected to slot [5798] located at 127.0.0.1:7002
OK
127.0.0.1:7002> get name
"haha"
127.0.0.1:7002>
[root@server1 7006]# redis-cli -c -p 7005
127.0.0.1:7005> get name
-> Redirected to slot [5798] located at 127.0.0.1:7002
"haha"
关掉7002
1159 ? Ssl 0:01 redis-server *:7001 [cluster]
1177 ? Ssl 0:00 redis-server *:7002 [cluster]
1185 ? Ssl 0:00 redis-server *:7003 [cluster]
1191 ? Ssl 0:00 redis-server *:7004 [cluster]
1197 ? Ssl 0:00 redis-server *:7005 [cluster]
1203 ? Ssl 0:00 redis-server *:7006 [cluster]
1221 pts/0 R+ 0:00 ps ax
[root@server1 7006]# kill 1177
查看添加时转到了7002的slave7004上
[root@server1 7006]# redis-cli -c -p 7005
127.0.0.1:7005> get name
-> Redirected to slot [5798] located at 127.0.0.1:7004
"haha"
127.0.0.1:7004>
完整代码
[root@server1 7006]# redis-cli -c -p 7001
127.0.0.1:7001> set name haha
-> Redirected to slot [5798] located at 127.0.0.1:7002
OK
127.0.0.1:7002> get name
"haha"
127.0.0.1:7002>
[root@server1 7006]# redis-cli -c -p 7005
127.0.0.1:7005> get name
-> Redirected to slot [5798] located at 127.0.0.1:7002
"haha"
127.0.0.1:7002>
[root@server1 7006]# ps ax
PID TTY STAT TIME COMMAND
1 ? Ss 0:00 /sbin/init
2 ? S 0:00 [kthreadd]
3 ? S 0:00 [migration/0]
4 ? S 0:00 [ksoftirqd/0]
5 ? S 0:00 [migration/0]
6 ? S 0:00 [watchdog/0]
7 ? S 0:00 [events/0]
8 ? S 0:00 [cgroup]
9 ? S 0:00 [khelper]
10 ? S 0:00 [netns]
11 ? S 0:00 [async/mgr]
12 ? S 0:00 [pm]
13 ? S 0:00 [sync_supers]
14 ? S 0:00 [bdi-default]
15 ? S 0:00 [kintegrityd/0]
16 ? S 0:00 [kblockd/0]
17 ? S 0:00 [kacpid]
18 ? S 0:00 [kacpi_notify]
19 ? S 0:00 [kacpi_hotplug]
20 ? S 0:00 [ata_aux]
21 ? S 0:00 [ata_sff/0]
22 ? S 0:00 [ksuspend_usbd]
23 ? S 0:00 [khubd]
24 ? S 0:00 [kseriod]
25 ? S 0:00 [md/0]
26 ? S 0:00 [md_misc/0]
27 ? S 0:00 [linkwatch]
28 ? S 0:00 [khungtaskd]
29 ? S 0:00 [kswapd0]
30 ? SN 0:00 [ksmd]
32 ? S 0:00 [aio/0]
33 ? S 0:00 [crypto/0]
38 ? S 0:00 [kthrotld/0]
40 ? S 0:00 [kpsmoused]
41 ? S 0:00 [usbhid_resumer]
71 ? S 0:00 [kstriped]
133 ? S 0:00 [scsi_eh_0]
134 ? S 0:00 [scsi_eh_1]
222 ? S 0:00 [virtio-blk]
252 ? S 0:00 [kdmflush]
254 ? S 0:00 [kdmflush]
272 ? S 0:00 [flush-253:0]
273 ? S 0:00 [jbd2/dm-0-8]
274 ? S 0:00 [ext4-dio-unwrit]
344 ? S<s 0:00 /sbin/udevd -d
375 ? S 0:00 [virtio-net]
385 ? S 0:00 [hd-audio0]
396 ? S 0:00 [vballoon]
588 ? S< 0:00 /sbin/udevd -d
617 ? S 0:00 [jbd2/vda1-8]
618 ? S 0:00 [ext4-dio-unwrit]
667 ? S 0:00 [kauditd]
853 ? S<sl 0:00 auditd
869 ? Sl 0:00 /sbin/rsyslogd -i /var/run/syslogd.pid -c 5
908 ? Ss 0:00 /usr/sbin/sshd
994 ? Ss 0:00 /usr/libexec/postfix/master
1002 ? Ss 0:00 crond
1005 ? S 0:00 pickup -l -t fifo -u
1006 ? S 0:00 qmgr -l -t fifo -u
1017 ? Ss 0:00 /usr/bin/rhsmcertd
1031 tty1 Ss+ 0:00 /sbin/mingetty /dev/tty1
1033 tty2 Ss+ 0:00 /sbin/mingetty /dev/tty2
1035 tty3 Ss+ 0:00 /sbin/mingetty /dev/tty3
1037 tty4 Ss+ 0:00 /sbin/mingetty /dev/tty4
1039 tty5 Ss+ 0:00 /sbin/mingetty /dev/tty5
1041 tty6 Ss+ 0:00 /sbin/mingetty /dev/tty6
1042 ? Ss 0:00 sshd: root@pts/0
1044 pts/0 Ss 0:00 -bash
1159 ? Ssl 0:01 redis-server *:7001 [cluster]
1177 ? Ssl 0:00 redis-server *:7002 [cluster]
1185 ? Ssl 0:00 redis-server *:7003 [cluster]
1191 ? Ssl 0:00 redis-server *:7004 [cluster]
1197 ? Ssl 0:00 redis-server *:7005 [cluster]
1203 ? Ssl 0:00 redis-server *:7006 [cluster]
1221 pts/0 R+ 0:00 ps ax
[root@server1 7006]# kill 1177
[root@server1 7006]# redis-cli -c -p 7005
127.0.0.1:7005> get name
-> Redirected to slot [5798] located at 127.0.0.1:7004
"haha"
127.0.0.1:7004>
[root@server1 7006]# cd ..
[root@server1 cluster]# cd 7002
[root@server1 7002]# redis-server redis.conf
[root@server1 7002]# redis-cli -c -p 7005
127.0.0.1:7005> get name
-> Redirected to slot [5798] located at 127.0.0.1:7004
"haha"
127.0.0.1:7004>
[root@server1 7002]# redis-cli -c -p 7002
127.0.0.1:7002> get name
-> Redirected to slot [5798] located at 127.0.0.1:7004
"haha"
127.0.0.1:7004>
[root@server1 7002]# redis-trib.rb check 127.0.0.1:7002
>>> Performing Cluster Check (using node 127.0.0.1:7002)
S: f1cdb7fa64c6d0d7de2e3eec6129bb64afa43fcc 127.0.0.1:7002
slots: (0 slots) slave
replicates 55b2ad81d088d226f9147fbb1b530c6cf7c9b0dd
S: fea2346dca69ef1c7c135a5ee8f6f66b53f87084 127.0.0.1:7005
slots: (0 slots) slave
replicates b0f217fab8742227d97e3a5b1f8b21b85ddc9460
M: b916ffb165b1c6c2f29da1abb37bde53f83d2c7a 127.0.0.1:7001
slots:0-5460 (5461 slots) master
1 additional replica(s)
M: 55b2ad81d088d226f9147fbb1b530c6cf7c9b0dd 127.0.0.1:7004
slots:5461-10922 (5462 slots) master
1 additional replica(s)
S: c739d1c90876958e9045bd62b70c95fb740be0fe 127.0.0.1:7006
slots: (0 slots) slave
replicates b916ffb165b1c6c2f29da1abb37bde53f83d2c7a
M: b0f217fab8742227d97e3a5b1f8b21b85ddc9460 127.0.0.1:7003
slots:10923-16383 (5461 slots) master
1 additional replica(s)
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
Redis mysql nginx集群
Redis为端下来的目录
“`
[root@server1 ~]# ls
Redis
Redis 作 mysql 的缓存服务器
1. 安装 lnmp 环境,安装以下软件包:php-gd php-mbstring php-mysql
php-pdo php-devel mysql mysql-server
nginx php php-fpm php-cli php-common
[root@server1 ~]# cd redis/
[root@server1 redis]# ls
codis-release3.2.zip php-cli-5.3.3-38.el6.x86_64.rpm
gearman-1.1.2.tgz php-common-5.3.3-38.el6.x86_64.rpm
gearmand-1.1.8-2.el6.x86_64.rpm php-devel-5.3.3-38.el6.x86_64.rpm
gearman-mysql-udf-0.6.tar.gz php-fpm-5.3.3-38.el6.x86_64.rpm
go1.8.linux-amd64.tar.gz php-gd-5.3.3-38.el6.x86_64.rpm
jemalloc-3.6.0-1.el6.x86_64.rpm php-mbstring-5.3.3-38.el6.x86_64.rpm
jemalloc-devel-3.6.0-1.el6.x86_64.rpm php-mysql-5.3.3-38.el6.x86_64.rpm
libevent-1.4.13-4.el6.x86_64.rpm php-pdo-5.3.3-38.el6.x86_64.rpm
libevent-devel-1.4.13-4.el6.x86_64.rpm phpredis-master.zip
libevent-doc-1.4.13-4.el6.noarch.rpm redis-3.0.2.tar.gz
libevent-headers-1.4.13-4.el6.noarch.rpm redis-4.0.1.gem
libgearman-1.1.8-2.el6.x86_64.rpm redis-4.0.1.tar.gz
libgearman-devel-1.1.8-2.el6.x86_64.rpm redis-4.0.8.tar.gz
lib_mysqludf_json-master.zip rhel6 Redis.pdf
libyaml-0.1.3-4.el6_6.x86_64.rpm ruby-2.2.3-1.el6.x86_64.rpm
nginx-1.10.2-1.el6.x86_64.rpm rubygems-1.3.7-5.el6.noarch.rpm
nginx-1.8.0-1.el6.ngx.x86_64.rpm test.php
nginx-all-modules-1.10.2-1.el6.noarch.rpm test.sql
nginx-filesystem-1.10.2-1.el6.noarch.rpm tokyocabinet-1.4.33-6.el6.x86_64.rpm
php-5.3.3-38.el6.x86_64.rpm worker.php
[root@server1 redis]# yum install -y nginx-1.8.0-1.el6.ngx.x86_64.rpm php-*
[root@server1 redis]# cd /etc/php.d/
[root@server1 php.d]# ls
curl.ini json.ini mysql.ini pdo_sqlite.ini zip.ini
fileinfo.ini mbstring.ini pdo.ini phar.ini
gd.ini mysqli.ini pdo_mysql.ini sqlite3.ini
[root@server1 php.d]# vim /etc/php.ini
extension=redis.so
加载 redis 模块
“`
更改时区
[root@server1 php.d]# id nginx
uid=498(nginx) gid=499(nginx) groups=499(nginx)
[root@server1 php.d]# cd /etc/php-fpm.d/
[root@server1 php-fpm.d]# ls
www.conf
[root@server1 php-fpm.d]# vim www.conf
将用户和组都改为nginx
[root@server1 php-fpm.d]# /etc/init.d/php-fpm start
Starting php-fpm: [ OK ]
端口9000
[root@server1 php-fpm.d]# netstat -antlp
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 908/sshd
tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN 994/master
tcp 0 0 127.0.0.1:9000 0.0.0.0:* LISTEN 1341/php-fpm
[root@server1 nginx]# cd conf.d/
[root@server1 conf.d]# ls
default.conf example_ssl.conf
简单配置nginx
[root@server1 conf.d]# vim default.conf
[root@server1 conf.d]# cd /usr/share/nginx/html/
[root@server1 html]# ls
50x.html index.html
[root@server1 html]# vim index.php
[root@server1 html]# cat index.php
<?php
phpinfo()
?>
[root@server1 conf.d]# /etc/init.d/nginx start
Starting nginx: [ OK ]
[root@server1 conf.d]# netstat -antlp
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 1360/nginx
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 908/sshd
tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN 994/master
tcp 0 0 127.0.0.1:9000 0.0.0.0:* LISTEN 1341/php-fpm
[root@server1 redis]# cat test.php
<?php
$redis = new Redis();
$redis->connect('127.0.0.1',6379) or die ("could net connect redis server");
# $query = "select * from test limit 9";
$query = "select * from test";
for ($key = 1; $key < 10; $key++)
{
if (!$redis->get($key))
{
$connect = mysql_connect('127.0.0.1','redis','westos');
mysql_select_db(test);
$result = mysql_query($query);
//如果没有找到$key,就将该查询sql的结果缓存到redis
while ($row = mysql_fetch_assoc($result))
{
$redis->set($row['id'],$row['name']);
}
$myserver = 'mysql';
break;
}
else
{
$myserver = "redis";
$data[$key] = $redis->get($key);
}
}
echo $myserver;
echo "<br>";
for ($key = 1; $key < 10; $key++)
{
echo "number is <b><font color=#FF0000>$key</font></b>";
echo "<br>";
echo "name is <b><font color=#FF0000>$data[$key]</font></b>";
echo "<br>";
}
?>
[root@server1 redis]# cp test.php /usr/share/nginx/html/index.php
cp: overwrite `/usr/share/nginx/html/index.php'? y
[root@server1 redis]# cd /usr/share/nginx/html/
创建php测试页面
[root@server1 html]# vim index.php
[root@server1 redis]# yum install -y unzip
[root@server1 redis]# unzip phpredis-master.zip
[root@server1 redis]# cd phpredis-master
[root@server1 phpredis-master]# ls
common.h debian.control mkdeb-apache2.sh redis_session.c
config.m4 igbinary php_redis.h redis_session.h
CREDITS library.c README.markdown serialize.list
debian library.h redis.c tests
[root@server1 phpredis-master]# phpize
Configuring for:
PHP Api Version: 20090626
Zend Module Api No: 20090626
Zend Extension Api No: 220090626
[root@server1 phpredis-master]# ./configure
[root@server1 phpredis-master]# make
[root@server1 phpredis-master]# make install
Installing shared extensions: /usr/lib64/php/modules/
[root@server1 phpredis-master]# cd /usr/lib64/php/modules/
[root@server1 modules]# cd /etc/php.d/
[root@server1 php.d]# ls
curl.ini json.ini mysql.ini pdo_sqlite.ini zip.ini
fileinfo.ini mbstring.ini pdo.ini phar.ini
gd.ini mysqli.ini pdo_mysql.ini sqlite3.ini
[root@server1 php.d]# cp mysql.ini redis.ini
[root@server1 php.d]# vim redis.ini
[root@server1 php.d]# cat redis.ini
extension=redis.so
[root@server1 php.d]# /etc/init.d/php-fpm reload
Reloading php-fpm: [12-Aug-2018 11:57:59] NOTICE: configuration file /etc/php-fpm.conf test is successful
[ OK ]
[root@server1 php.d]# php -m |grep redis
redis
配置mysql 需要5.7以下版本
[root@server3 ~]# /etc/init.d/redis_6379 stop
Stopping ...
Redis stopped
[root@server3 ~]# rpm -qa|grep mysql
mysql-community-common-5.7.17-1.el6.x86_64
mysql-community-client-5.7.17-1.el6.x86_64
mysql-community-libs-compat-5.7.17-1.el6.x86_64
mysql-community-libs-5.7.17-1.el6.x86_64
mysql-community-server-5.7.17-1.el6.x86_64
mha4mysql-node-0.56-0.el6.noarch
[root@server3 ~]# cd /var/lib/mysql
[root@server3 mysql]# ls
auto.cnf client-key.pem performance_schema server-cert.pem
binlog.000001 ib_buffer_pool private_key.pem server-key.pem
binlog.index ibdata1 public_key.pem sys
ca-key.pem ib_logfile0 server3-relay-bin.000001
ca.pem ib_logfile1 server3-relay-bin.000002
client-cert.pem mysql server3-relay-bin.index
[root@server3 mysql]# rm -rf *
[root@server3 mysql]# ls
[root@server3 ~]# rpm -e --nodeps `rpm -qa|grep mysql`
warning: /etc/my.cnf saved as /etc/my.cnf.rpmsave
[root@server3 ~]# yum install mysql-server -y
[root@server3 ~]# mysql
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| test |
+--------------------+
3 rows in set (0.00 sec)
mysql> grant all on test.* to redis@'%' identified by 'westos';
Query OK, 0 rows affected (0.00 sec)
[root@server3 ~]# vim test.sql
[root@server3 ~]# cat test.sql
use test;
CREATE TABLE `test` (`id` int(7) NOT NULL AUTO_INCREMENT, `name` char(8) DEFAULT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `test` VALUES (1,'test1'),(2,'test2'),(3,'test3'),(4,'test4'),(5,'test5'),(6,'test6'),(7,'test7'),(8,'test8'),(9,'test9');
#DELIMITER $$
#CREATE TRIGGER datatoredis AFTER UPDATE ON test FOR EACH ROW BEGIN
# SET @RECV=gman_do_background('syncToRedis', json_object(NEW.id as `id`, NEW.name as `name`));
# END$$
#DELIMITER ;
[root@server3 ~]# mysql < test.sql
[root@server3 ~]# mysql
mysql> use test
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
mysql> select * from test;
+----+-------+
| id | name |
+----+-------+
| 1 | test1 |
| 2 | test2 |
| 3 | test3 |
| 4 | test4 |
| 5 | test5 |
| 6 | test6 |
| 7 | test7 |
| 8 | test8 |
| 9 | test9 |
+----+-------+
9 rows in set (0.00 sec)
测试结果,第一次访问由于redis没有缓存,所以他会去mysql取
第二次访问就是mysql的数据
Server2
127.0.0.1:6379> get 1
"test1"
127.0.0.1:6379> get 2
"test2"
127.0.0.1:6379> get 3
"test3"
127.0.0.1:6379> get 9
"test9"
更新数据库
mysql> update test set name='westos' where id=1;
Query OK, 1 row affected (0.08 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> select * from test;
+----+--------+
| id | name |
+----+--------+
| 1 | westos |
| 2 | test2 |
| 3 | test3 |
| 4 | test4 |
| 5 | test5 |
| 6 | test6 |
| 7 | test7 |
| 8 | test8 |
| 9 | test9 |
+----+--------+
9 rows in set (0.00 sec)
到这里,我们已经实现了 redis 作为 mysql 的缓存服务器,但是如果更新了 mysql,redis
中仍然会有对应的 KEY,数据就不会更新,此时就会出现 mysql 和 redis 数据不一致的情
况。所以接下来就要通过 mysql 触发器将改变的数据同步到 redis 中。
配置 gearman 实现数据同步
Gearman 是一个支持分布式的任务分发框架:
Gearman Job Server: Gearman 核心程序,需要编译安装并以守护进程形式运行在后台。
Gearman Client:可以理解为任务的请求者。
Gearman Worker:任务的真正执行者,一般需要自己编写具体逻辑并通过守护进程方式
运行,Gearman Worker 接收到 Gearman Client 传递的任务内容后,会按顺序处理。
大致流程:下面要编写的 mysql 触发器,就相当于 Gearman 的客户端。修改表,插入表就相当于直接
下发任务。然后通过 lib_mysqludf_json UDF 库函数将关系数据映射为 JSON 格式,然后
在通过 gearman-mysql-udf 插件将任务加入到 Gearman 的任务队列中,最后通过
redis_worker.php,也就是 Gearman 的 worker 端来完成 redis 数据库的更新。
[root@server1 redis]# ls
codis-release3.2.zip php-common-5.3.3-38.el6.x86_64.rpm
gearman-1.1.2.tgz php-devel-5.3.3-38.el6.x86_64.rpm
gearmand-1.1.8-2.el6.x86_64.rpm php-fpm-5.3.3-38.el6.x86_64.rpm
gearman-mysql-udf-0.6.tar.gz php-gd-5.3.3-38.el6.x86_64.rpm
go1.8.linux-amd64.tar.gz php-mbstring-5.3.3-38.el6.x86_64.rpm
jemalloc-3.6.0-1.el6.x86_64.rpm php-mysql-5.3.3-38.el6.x86_64.rpm
jemalloc-devel-3.6.0-1.el6.x86_64.rpm php-pdo-5.3.3-38.el6.x86_64.rpm
libevent-1.4.13-4.el6.x86_64.rpm phpredis-master
libevent-devel-1.4.13-4.el6.x86_64.rpm phpredis-master.zip
libevent-doc-1.4.13-4.el6.noarch.rpm redis-3.0.2.tar.gz
libevent-headers-1.4.13-4.el6.noarch.rpm redis-4.0.1.gem
libgearman-1.1.8-2.el6.x86_64.rpm redis-4.0.1.tar.gz
libgearman-devel-1.1.8-2.el6.x86_64.rpm redis-4.0.8.tar.gz
lib_mysqludf_json-master.zip rhel6 Redis.pdf
libyaml-0.1.3-4.el6_6.x86_64.rpm ruby-2.2.3-1.el6.x86_64.rpm
nginx-1.10.2-1.el6.x86_64.rpm rubygems-1.3.7-5.el6.noarch.rpm
nginx-1.8.0-1.el6.ngx.x86_64.rpm test.php
nginx-all-modules-1.10.2-1.el6.noarch.rpm test.sql
nginx-filesystem-1.10.2-1.el6.noarch.rpm tokyocabinet-1.4.33-6.el6.x86_64.rpm
php-5.3.3-38.el6.x86_64.rpm worker.php
php-cli-5.3.3-38.el6.x86_64.rpm
1. 安装 gearman 软件包:
[root@server1 redis]# yum install -y gearmand-1.1.8-2.el6.x86_64.rpm libevent-* libgearman-*
启动服务
[root@server1 redis]# /etc/init.d/gearmand start
Starting gearmand: [ OK ]
[root@server3 ~]# yum install -y unzip
[root@server3 ~]# unzip lib_mysqludf_json-master.zip
[root@server3 ~]# cd lib_mysqludf_json-master
[root@server3 lib_mysqludf_json-master]# ls
lib_mysqludf_json.c lib_mysqludf_json.so README.md
lib_mysqludf_json.html lib_mysqludf_json.sql
[root@server3 lib_mysqludf_json-master]# yum install -y gcc mysql-devel
[root@server3 lib_mysqludf_json-master]# gcc $(mysql_config --cflags) -shared -fPIC -o lib_mysqludf_json.so lib_mysqludf_json.c
[root@server3 plugin]# cd -
/root/lib_mysqludf_json-master
[root@server3 lib_mysqludf_json-master]# cp lib_mysqludf_json.so /usr/lib64/mysql/plugin/
[root@server3 lib_mysqludf_json-master]# mysql
查看 mysql 的模块目录:
mysql> show global variables like 'plugin_dir';
+---------------+-------------------------+
| Variable_name | Value |
+---------------+-------------------------+
| plugin_dir | /usr/lib64/mysql/plugin |
+---------------+-------------------------+
1 row in set (0.00 sec)
注册 UDF 函数
mysql> CREATE FUNCTION json_object RETURNS STRING SONAME 'lib_mysqludf_json.so';
Query OK, 0 rows affected (0.00 sec)
安装 gearman-mysql-udf
这个插件是用来管理调用 Gearman 的分布式的队列。
[root@server3 ~]# tar zxf gearman-mysql-udf-0.6.tar.gz
[root@server3 ~]# cd gearman-mysql-udf-0.6
[root@server3 gearman-mysql-udf-0.6]# ls
aclocal.m4 ChangeLog config.h.in configure.ac libgearman_mysql_udf Makefile.am NEWS
AUTHORS config configure COPYING m4 Makefile.in README
[root@server3 ~]# ls
anaconda-ks.cfg
gearman-mysql-udf-0.6
gearman-mysql-udf-0.6.tar.gz
install.log
install.log.syslog
libevent-1.4.13-4.el6.x86_64.rpm
libevent-devel-1.4.13-4.el6.x86_64.rpm
libevent-doc-1.4.13-4.el6.noarch.rpm
libevent-headers-1.4.13-4.el6.noarch.rpm
libgearman-1.1.8-2.el6.x86_64.rpm
libgearman-devel-1.1.8-2.el6.x86_64.rpm
lib_mysqludf_json-master
lib_mysqludf_json-master.zip
mha4mysql-node-0.56-0.el6.noarch.rpm
mysql-community-client-5.7.17-1.el6.x86_64.rpm
mysql-community-common-5.7.17-1.el6.x86_64.rpm
mysql-community-libs-5.7.17-1.el6.x86_64.rpm
mysql-community-libs-compat-5.7.17-1.el6.x86_64.rpm
mysql-community-server-5.7.17-1.el6.x86_64.rpm
redis-4.0.8
redis-4.0.8.tar.gz
test.sql
[root@server3 ~]# yum install -y libgearman-* libevent-*
[root@server3 gearman-mysql-udf-0.6]# ./configure --libdir=/usr/lib64/mysql/plugin/
Make && make install
[root@server3 ~]# mysql
注册 UDF 函数
mysql> CREATE FUNCTION gman_do_background RETURNS STRING SONAME 'libgearman_mysql_udf.so';
Query OK, 0 rows affected (0.00 sec)
mysql> CREATE FUNCTION gman_servers_set RETURNS STRING SONAME 'libgearman_mysql_udf.so';
Query OK, 0 rows affected (0.00 sec)
查看函数
mysql> select * from mysql.func;
+--------------------+-----+-------------------------+----------+
| name | ret | dl | type |
+--------------------+-----+-------------------------+----------+
| json_object | 0 | lib_mysqludf_json.so | function |
| gman_do_background | 0 | libgearman_mysql_udf.so | function |
| gman_servers_set | 0 | libgearman_mysql_udf.so | function |
+--------------------+-----+-------------------------+----------+
3 rows in set (0.00 sec)
指定 gearman 的服务信息
mysql> SELECT gman_servers_set('172.25.53.1:4730');
+--------------------------------------+
| gman_servers_set('172.25.53.1:4730') |
+--------------------------------------+
| 172.25.53.1:4730 |
+--------------------------------------+
1 row in set (0.00 sec)
编写 mysql 触发器(根据实际情况编写)
[root@server3 ~]# vim test.sql
[root@server3 ~]# cat test.sql
use test;
#CREATE TABLE `test` (`id` int(7) NOT NULL AUTO_INCREMENT, `name` char(8) DEFAULT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;
#INSERT INTO `test` VALUES (1,'test1'),(2,'test2'),(3,'test3'),(4,'test4'),(5,'test5'),(6,'test6'),(7,'test7'),(8,'test8'),(9,'test9');
DELIMITER $$
CREATE TRIGGER datatoredis AFTER UPDATE ON test FOR EACH ROW BEGIN
SET @RECV=gman_do_background('syncToRedis', json_object(NEW.id as `id`, NEW.name as `name`));
END$$
DELIMITER ;
[root@server3 ~]# mysql < test.sql
[root@server3 ~]# mysql
查看触发器
mysql> SHOW TRIGGERS FROM test;
+-------------+--------+-------+----------------------------------------------------------------------------------------------------------------+--------+---------+----------+----------------+----------------------+----------------------+--------------------+
| Trigger | Event | Table | Statement | Timing | Created | sql_mode | Definer | character_set_client | collation_connection | Database Collation |
+-------------+--------+-------+----------------------------------------------------------------------------------------------------------------+--------+---------+----------+----------------+----------------------+----------------------+--------------------+
| datatoredis | UPDATE | test | BEGIN
SET @RECV=gman_do_background('syncToRedis', json_object(NEW.id as `id`, NEW.name as `name`));
END | AFTER | NULL | | root@localhost | latin1 | latin1_swedish_ci | latin1_swedish_ci |
+-------------+--------+-------+----------------------------------------------------------------------------------------------------------------+--------+---------+----------+----------------+----------------------+----------------------+--------------------+
1 row in set (0.00 sec)
Server1
[root@server1 redis]# cd /usr/local/
[root@server1 local]# ls
bin cluster etc games include lib lib64 libexec sbin share src worker.php
[root@server1 local]# vim worker.php
编写 gearman 的 worker 端
[root@server1 local]# cat worker.php
<?php
$worker = new GearmanWorker();
$worker->addServer();
$worker->addFunction('syncToRedis', 'syncToRedis');
$redis = new Redis();
$redis->connect('172.25.53.2', 6379);
while($worker->work());
function syncToRedis($job)
{
global $redis;
$workString = $job->workload();
$work = json_decode($workString);
if(!isset($work->id)){
return false;
}
$redis->set($work->id, $work->name);
}
?>
[root@server1 local]# cd
[root@server1 ~]# cd redis/
[root@server1 redis]# tar zxf gearman-1.1.2.tgz
[root@server1 redis]# cd gearman-1.1.2
[root@server1 gearman-1.1.2]# phpize
Configuring for:
PHP Api Version: 20090626
Zend Module Api No: 20090626
Zend Extension Api No: 220090626
[root@server1 gearman-1.1.2]# ./configure
Make && makeinstall
[root@server1 gearman-1.1.2]# make install
Installing shared extensions: /usr/lib64/php/modules/
[root@server1 modules]# cd /etc/php.d/
[root@server1 php.d]# cp redis.ini gearman.ini
[root@server1 php.d]# vim gearman.ini
[root@server1 php.d]# vim gearman.ini
[root@server1 php.d]# cat gearman.ini
extension=gearman.so
[root@server1 php.d]# /etc/init.d/php-fpm reload
Reloading php-fpm: [12-Aug-2018 15:22:06] NOTICE: configuration file /etc/php-fpm.conf test is successful
[ OK ]
[root@server1 php.d]# php -m |grep gearman
Gearman
后台运行 worker
[root@server1 php.d]# nohup php /usr/local/worker.php &
操作数据库
mysql> use test
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
更新 mysql 中的数据
mysql> update test set name = 'redhat';
Query OK, 9 rows affected (0.09 sec)
Rows matched: 9 Changed: 9 Warnings: 0
刷新测试页面数据同步