标签归档:缓存数据库

如何在CentOS 7上配置 Redis Replication 主从复制群集

关于 Redis Replication

Redis支持异步主从复制,允许一个或多个Redis服务器 隶属于Redis Master服务器的精确副本。Redis主从复制的配置是非常简单的,只需安装几个步骤即可。有关Redis更多信息,请参阅官方的Redis复制文档

对于生产环境,将数据复制到至少两个节点被认为是最佳的做法。这允许在环境故障的情况下恢复,这在您的应用程序用户基础增长以及体验尤为重要。它还允许您安全地与生产数据交互,而无需修改或影响性能。

1.规划(由于资源有限,暂用2台Server做为测试):

OS:CentOS 7.4
Redis 4.0.1
Redis Master 10.10.204.64
Redis Slave 10.10.204.65

2.配置Redis Replication之前首先需要安装Redis实例服务:

Linux Centos7 Redis 4.0.1 源码编译安装配置

3.主从互相添加Hosts:

主服务器:

 # echo “10.10.204.64 10-10-204-64” >> /etc/hosts
 # echo “10.10.204.65 10-10-204-65” >> /etc/hosts

从服务器:

 # echo “10.10.204.65 10-10-204-65” >> /etc/hosts
 # echo “10.10.204.64 10-10-204-64” >> /etc/hosts

4.Redis.conf 配置文件:

其实Slave的配置和Master基本一致,为什么这么说呢,当Master挂掉之后,那么Slave就担任了Master工作,所以一些参数就必须和Master相同,所以主从分别,只需要修改相应的pidfile,端口,日志文件名,并配上Master的地址和认证密码即可,生产环境亦是如此。

Master & Slave 通用配置:

 # vim /usr/local/redis/redis.conf
 port 6379 #端口信息
 daemonize yes #如果需要在后台运行,把该项改为yes
 pidfile /var/run/redis_6379.pid #主从PID路径
 logfile "/usr/local/redis/log/redis.log" #设置日志文件路径
 requirepass RenwoleQxl5qpKHrh9khuTW #设置设置256位连接密码
 masterauth RenwoleQxl5qpKHrh9khuTW #如果Master设置了密码,则Slave需要通过masterauth配置密码
 repl-diskless-sync yes #无硬盘复制功能通过以下配置
 repl-diskless-sync-delay 5
 maxmemory-policy volatile-lru #最大内存策略:如果达到内存限制了,Redis如何选择删除key.多选
 repl-ping-slave-period 10 #多少秒ping一次Master
 repl-timeout 60 #复制的超时时间,这个时间一定要大于ping的时间
 timeout 300 #客户端闲置多长时间后断开连接,默认为0关闭此功能
 min-slaves-to-write 3 #最小slave链接数默认为0
 min-slaves-max-lag 10 #最小的slave,最大延迟数默认为10
 dir /usr/local/redis-4.0.1 #自定义数据存储路径
 tcp-keepalive 60 #建议60,首先找到设置并将其设置为60秒
 appendonly yes 为了提高耐用性保证,可以启用仅追加文件的持久性,这助于最大程度减少系统故障时的数据丢失,同时IO的读写会付出相应的代价
 appendfilename "redis-staging-ao.aof"
 repl-backlog-ttl 3600 #在某些时候, master 不再连接 slaves,backlog 将被释放。如果设置为 0 意味着不释放 backlog
 maxclients 10000 #当连接数超过这个值时,redis 将不再接收其他连接请求,客户端尝试连接时将收到 error 信息

5.Master 配置:

bind 127.0.0.1 10.10.204.64

6.Slave 配置:

 bind 127.0.0.1 10.10.204.65
 slaveof 10.10.204.64 6379 #设置Master的IP与端口

注意:当从服务器执行了slaveof命令后,从服务器中原来的数据将清空,重新加载主服务器中的数据。

7.重新启动 Master & Slave 查看主从连接状态:

 # systemctl restart redis

8.查看 Master 角色以及Slave连接状态(注意:红色部分):

 # redis-cli
 10.10.204.64:6379> auth RenwoleQxl5qpKHrh9khuTW
 OK
 10.10.204.64:6379> info Replication

 # Replication
 role:master
 connected_slaves:1
 slave0:ip=10.10.204.65,port=6379,state=online,offset=101640,lag=1
 master_replid:cd78097afde482dd3ef18cf74ec66da7f2d7d140
 master_replid2:0000000000000000000000000000000000000000
 master_repl_offset:101640
 ...

9.查看Slave角色以及连接Master的状态(注意:红色部分):

 # redis-cli
 10.10.204.65:6379> auth RenwoleQxl5qpKHrh9khuTW
 OK
 10.10.204.65:6379> info Replication
 # Replication
 role:slave
 master_host:10.10.204.64
 master_port:6379
 master_link_status:up
 master_last_io_seconds_ago:7
 master_sync_in_progress:0
 slave_repl_offset:101906
 slave_priority:100
 slave_read_only:1
 connected_slaves:0
 ...

10.在Master节点上操作:

 10.10.204.64:6379> set key renwole.com
 OK
 10.10.204.64:6379> scan 0
 1) "0"
 2) 1) "name"
 2) "key"
 3) "name1"

11.检查Slave节点是否同步:

 10.10.204.65:6379> scan 0
 1) "0"
 2) 1) "key"
 2) "name1"
 3) "name"
 10.10.204.65:6379> get key
 "renwole.com"

Slave信息显示已经成功同步。

:Redis Replication 配置要求需要两台或多台redis实例之间保证端口相互通信,否则不能正常实现Redis复制。

12.Redis主从复制看起来完美无瑕,但由于Redis目前仅支持主从复制备份,而无法提供故障自动切换。所以这并不能满足我们的业务需求。

请参阅《Redis Sentinel冗余配置为Redis实例提供自动故障切换》高可用(HA)解决方案。

Redisson 缓存 Tomcat Redis Session Manager 变量

部署负载均衡时,使用一台Nginx作为前端服务器,多台Tomcat作为后端服务器。Nginx 会根据负载策略把请求分发给Tomcat服务器。默认Tomcat服务器的session(共享会话)是不可跨越服务器的,若是同一个用户的不同请求被分发到不同的Tomcat服务器,就会造成 session 变量丢失,需要用户重新登录。在讲解Redisson之前,我先来分析以下两种方案的Session会话共享。

方案一:Nginx原生 Upstream ip_hash

ip_hash 是根据请求的IP进行分发,对于同一个IP的请求会转发到同一台Tomcat服务器。

1.Nginx 配置如下:《Nginx 1.3 集群负载均衡器 反向代理安装配置优化

 upstream webservertomcat {
 ip_hash;
 server 10.10.204.63:8023 weight=1 max_fails=2 fail_timeout=2;
 server 10.10.204.64:8023 weight=1 max_fails=2 fail_timeout=2;
 #server 127.0.0.1:8080 backup;
 }
 server {
 listen 80;
 server_name www.myname.com myname.com;
 location / {
 proxy_pass //webservertomcat;
 proxy_redirect off;
 proxy_set_header Host $host;
 proxy_set_header X-Real-IP $remote_addr;
 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
 client_max_body_size 10m;
 client_body_buffer_size 128k;
 proxy_connect_timeout 90;
 proxy_send_timeout 90;
 proxy_read_timeout 90;
 proxy_buffer_size 4k;
 proxy_buffers 4 32k;
 proxy_busy_buffers_size 64k;
 proxy_temp_file_write_size 64k;
 add_header Access-Control-Allow-Origin *;
 }
 }

以上配置生产环境不建议使用,原因有二:

1.Nginx可能不是最前端的服务器,如Squid或CDN作为前端缓存,则Nginx实际是拿Squid或CDN服务器的IP地址,达不到根据客户端请求IP分流的效果。
2.有些机构是使用动态虚拟IP或有多个出口IP,用户访问会切换IP,则无法将某个用户的请求固定到同一个Tomcat服务器。

方案二:Nginx_Upstream_jvm_route

Nginx_upstream_jvm_route 是一个第三方 nginx 扩展模块,该模块通过 session cookie 实现 session 会话粘性,如果在cookie和url中并没有session,则这只是个简单的round-robin 负载均衡。

实现方法:用户初次请求分发到后端Server时;会把响应的Server标识添加到名称为JSESSIONID的cookie中,再次请求时;jvm_route看到session中有后端服务器的名称,它就把请求转到对应的服务器上。模块地址://code.google.com/archive/p/nginx-upstream-jvm-route/

1.Nginx配置如下:

 upstream tomcats_jvm_route {
 server 10.10.204.63:8023 srun_id=tomcat1;
 server 10.10.204.64:8023 srun_id=tomcat2;
 jvm_route $cookie_JSESSIONID|sessionid reverse;
 }

2.在多个Tomcat的server.xml添加配置如下:

 <Engine name="Catalina" defaultHost="localhost" jvmRoute="tomcat1">
 <Engine name="Catalina" defaultHost="localhost" jvmRoute="tomcat2">

3.配置后,请求的名称为JSESSIONID的cookie末尾会被添加服务器标识,如下:

 JSESSIONID=33775B80D8E0DB5AEAD61F86D6666C45.tomcat2;

4.生产环境不建议使用,原因:

4.1根据tomcat的特性,当server.xml配置文件中加了jvmRoute值后,会给sessionid加上jvmRoute值的后缀,根据这一特性 nginx_upstream_jvm_route对每次访问请求中的sessionId的值自动匹配对应的server。这样就会每次都访问都会到同一个Tomcat Server,这样就解决了访问不同tomcat节点session发生变化的问题。但是这种方式会出现一个问题,当一直被访问的Tomcat服务器宕机后,负载就会将用户分配到其他Server,这样就会造成session发生变化,从而就需要重新登录。

方案三:Tomcat Redis Session Manager

使用 Redis 共享 session,也就是本节中重点讲解的部分。以上两种方案均是将Session存储在Tomcat容器中,当请求从一个Tomcat转发到另一个Tomcat时,Session就会失效,因为Session在各个Tomcat中不能共享。如果使用Redis等缓存数据库系统存储Session,就可以在Tomcat实例之间实现Session共享。

Java框架redisson实现Tomcat会话管理器(Tomcat Session Manager),支持Apache Tomcat 6.x,7.x和8.x。配置方法如下:

1.编辑 TOMCAT_BASE/conf/context.xml 文件节点,添加以下内容:

<Manager className="org.redisson.tomcat.RedissonSessionManager"<Manager className="org.redisson.tomcat.RedissonSessionManager"  configPath="${catalina.base}/redisson-config.json" />

注:configPath – 是指的Redisson的JSON或YAML格式的配置文件路径。配置文件详见这里

2.拷贝相应的***两个***JAR包到指定的TOMCAT_BASE/lib目录下:

适用于 JDK 1.8+

redisson-all-3.5.0.jar

for Tomcat 6.x

redisson-tomcat-6-3.5.0.jar

for Tomcat 7.x

redisson-tomcat-7-3.5.0.jar

for Tomcat 8.x

redisson-tomcat-8-3.5.0.jar

3.按照 [Single instance mode]单实例模式的说明,创建编辑 Json 格式的 redisson-config.json 文件,添加以下内容,并将其上传到TOMCAT_BASE下,重载Tomcat服务即可。

{
 "singleServerConfig":{
 "idleConnectionTimeout":10000,
 "pingTimeout":1000,
 "connectTimeout":10000,
 "timeout":3000,
 "retryAttempts":3,
 "retryInterval":1500,
 "reconnectionTimeout":3000,
 "failedAttempts":3,
 "password":null,
 "subscriptionsPerConnection":5,
 "clientName":null,
 "address": "redis://127.0.0.1:6379",
 "subscriptionConnectionMinimumIdleSize":1,
 "subscriptionConnectionPoolSize":50,
 "connectionMinimumIdleSize":10,
 "connectionPoolSize":64,
 "database":0,
 "dnsMonitoring":false,
 "dnsMonitoringInterval":5000
 },
 "threads":0,
 "nettyThreads":0,
 "codec":null,
 "useLinuxNativeEpoll":false
 }

4.开始测试session。创建session.jsp并添加以下代码,上传到TOMCAT_BASE/webapps/ROOT/下。

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>shared session</title>
</head>
<body>
<br>session id=<%=session.getId()%>
</body>
</html>

5.浏览器访问会出现以下会话信息

 session id=1D349A69E8F5A27E1C12DEEFC304F0DC

6.现在查看Redis中是否存储了该值,如果存在会话值,此时你重启Tomcat后,该会话值也不会发生变化。

 # redis-cli
 127.0.0.1:6379> keys *
 1) "redisson_tomcat_session:1D349A69E8F5A27E1C12DEEFC304F0DC"

已经存储成功。

如果是Redis集群或多实例模式,可参阅以下更多资料进行配置:

//github.com/redisson/redisson/wiki/14.-Integration%20with%20frameworks#144-tomcat-redis-session-manager
//github.com/redisson/redisson/wiki/2.-Configuration
//github.com/redisson/redisson/wiki/2.-%E9%85%8D%E7%BD%AE%E6%96%B9%E6%B3%95 (中文文档)

Redis 缓存 PHP 7.2 session 变量共享

一般负载均衡内容有两种形式,一种是静态,另一种是动态,动态网站内容就可能需要进行交互,那么就涉及到session共享的问题。默认PHP是将session存储在LocalDisk,如果是多台php主机之间进行负载,那么该如何共享session?今天我们就解决这个问题。

session会话共享文件有很多种方式:

分布式文件共享;NFS,NAS文件存储等。
Nginx负载均衡ip_hash模块,固定访客到后端某台服务器。
将session存储到数据库中;例如MySQL,Memcached,Redis,Mongodb等。

我个人比较倾向于将session存储到Redis数据库,用这种方式来同步session共享,不仅不会加大数据库的负担,而且安全性比cookie更高,把session放到内存里面,比从磁盘文件中读取会快很多。“有人认为;那我把所有的缓存软件都安装,速度岂不是更快,那就不是缓存加速了,而演变成了缓存库了”。

php语言脚本默认不支持对Redis的操作,所以需要安装第三方phpRedis扩展模块,让其支持对Redis的操作,至于如何安装使用phpRedis,可以参考我前面写的文章《phpRedis扩展模块安装配置使用》。此外这里还需要一台Redis服务器,请参阅《Linux Centos7 Redis 3.2.9 源码编译安装配置》。

1.修改PHP配置文件php.ini将session存储到Redis中。

# vim /usr/local/php/etc/php.ini

session.save_handler = files
;session.save_path = "N;/path"

修改为:

session.save_handler = Redis
session.save_path = “tcp://10.10.204.66:6379”

;如果Redis有密码连接方式
session.save_path = “tcp://10.10.204.66:6379?auth=password”

 

2.重启php-fpm服务生效

# systemctl restart php-fpm

以上所有过程均是经过手工测试的,99%可用于生产。

Linux Centos7 Redis 4.0.1 源码编译安装配置

最近做Nginx负载均衡配置,由于我们是交互性网站,必须用到session,尝试了多种方案,最后选择了Redis做为数据库缓存服务器。

Redis官方简介

Redis是一个开源(BSD许可),内存数据结构存储,用作数据库,缓存和消息代理。它支持的数据结构,例如字符串,散列,列表,集合,具有范围查询的排序集,位图,超文本和具有半径查询的地理空间索引。Redis内置复制,Lua脚本,LRU驱逐,事务和不同级别的磁盘持久性,并通过Redis Sentinel提供高可用性,并通过Redis Cluster进行自动分区。

进入正题,无论是物理或虚拟化服务器,Redis安装方法都没有区别,接下来我就开始安装操作。

 

实验OS:CentOS Linux release 7.3.1611 (Core) x64

 

1.先决扩展条件

安装扩展包以及依赖包
# yum install epel-release -y 
# yum install gcc gcc-c++ jemalloc-devel

2.Redis安装

下载解压 将其移动到/usr/local目录,创建目录以及用户和组,并给予目录权限,最后创建软连接。

# wget //download.redis.io/releases/redis-4.0.1.tar.gz
# tar zxvf redis-4.0.1.tar.gz
# mv redis-4.0.1 /usr/local/
# cd /usr/local/
# mkdir -p /usr/local/redis-4.0.1/logs
# mkdir -p /usr/local/redis-4.0.1/rdb
# groupadd redis
# useradd -g redis -s /sbin/nologin redis
# chown -R redis:redis /usr/local/redis-4.0.1/logs
# chown -R redis:redis /usr/local/redis-4.0.1/rdb
# chown redis:redis /usr/local/redis-4.0.1/redis.conf
# make && make install
# ln -s redis-4.0.1 redis

3.配置文件

生产环境中以下信息是必须修改的,所以可以根据自己的需求进行修改 /usr/local/redis-4.0.1/redis.conf 此文件

port 6379 #监听端口,默认是6379
daemonize yes #如果需要在后台运行,把该项改为yes
requirepass foobared #去掉前边#注释,修改foobared为你想配置的任意密码
bind 10.10.204.65 #默认bind的填写127.0.0.1这样配置是只允许本地访问,想远程访问就改本机网卡配置的ip地址。多个IP 请使用空格隔开
pidfile /usr/local/redis/logs/redis.pid
logfile "/usr/local/redis/logs/redis.log" #设置日志文件路径
dir /usr/local/redis-4.0.1/rdb #持久化文件存储路径
supervised systemd #默认为no,由于我们正在运行一个使用systemd init系统的操作系统,所以我们可以将其更改为systemd

除了上述几个设置外,还有其他的等一些参数,有需要可以按照配置文件的说明修改。

4.测试redis启动

 # /usr/local/redis/src/redis-server /usr/local/redis/redis.conf
 ...
 WARNING The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
 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.
 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.

可以看到存在3条启动警告信息:

第一个错误和第二个错误可以同时解决,第一个错误大概是说somaxconn的值128设置过小,此值受限于系统的somaxconn与tcp_max_syn_backlog这两个值,所以应该把这两个内核参数值调大,第二个错误是过量使用内存设置为0!在低内存环境下,后台保存可能失败。请在/etc/sysctl.conf 添加一项 ‘vm.overcommit_memory = 1′ ,然后重启(或者运行命令’sysctl vm.overcommit_memory=1’ )使其生效。

 # vim /etc/sysctl.conf
 net.core.somaxconn = 20480
 #最大队列长度,应付突发的大并发连接请求,默认为128
 net.ipv4.tcp_max_syn_backlog = 20480
 #半连接队列长度,此值受限于内存大小,默认为1024
 vm.overcommit_memory = 1
 #过量使用内存设置为0!
 # sysctl -p

第三个警告错误是需要关闭Linux (THP) 透明内存

 # vim /etc/rc.local
 echo never > /sys/kernel/mm/transparent_hugepage/enabled #在开机脚本里追加此命令

至此3个错误已经解决,再次启动的时候就不会报警告信息。

5.创建一个Redis系统单元文件

# vim /usr/lib/systemd/system/redis.service
[Unit]
Description=Redis persistent key-value database
After=network.target

[Service]
User=redis
Group=redis
ExecStart=/usr/local/bin/redis-server /usr/local/redis/redis.conf --daemonize no
ExecStop=/usr/local/bin/redis-cli -p 6379 shutdown
Restart=always

[Install]
WantedBy=multi-user.target

6.启动redis并加入开机启动

# systemctl daemon-reload 
# systemctl start redis.service 
# systemctl enable redis.service

7.查看是否启动

# ps -A | grep redis
 6167 ? 00:00:00 redis-server

8.加入防火墙

# firewall-cmd --zone=public --add-port=6379/tcp --permanent
# firewall-cmd --reload
# firewall-cmd --zone=public --list-ports

9.测试连接成功

# redis-cli
127.0.0.1:6379>

到目前为止redis已经完成安装,其实生产环境的安装也是如此,只不过需求不同,redis.conf中的修改内容不同。

phpRedis扩展模块安装配置使用

phpRedis是什么?phpredis扩展提供了一个用于与Redis键值存储进行通信的API,如果需要使用Redis相关函数就必须安装phpRedis扩展包。看起来很复杂,其实动手操作真没那么难。

环境:

CentOS Linux release 7.3.1611 (Core) x64
Redis server v=3.2.9 sha=00000000:0 malloc=jemalloc-4.0.3 bits=64 build=37db043e44b54a88

1.下载phpRedis扩展并解压,下载地址:

//pecl.php.net/package/redis
# cd /tmp
# wget //github.com/phpredis/phpredis/archive/develop.zip# unzip develop.zip
# cd phpredis-develop/

2.接下来在phpredis-develop目录编译phpize扩展工具,主要作用就是在phpredis-develop目录生成configure文件。

 

# /usr/local/php/bin/phpize
Configuring for:
PHP Api Version: 20160303
Zend Module Api No: 20160303
Zend Extension Api No: 320160303

# ./configure --with-php-config=/usr/local/php/
# make && make install
...
Build complete.
Don't forget to run 'make test'.
Installing shared extensions: /usr/local/php/lib/php/extensions/no-debug-zts-20160303/

最后一行就是编译生成的Redis动态库路径:/usr/local/php/lib/php/extensions/no-debug-zts-20160303/

3.修改php.ini在该文件的底部加上Redis.so路径,之后重启nginx/php-fpm服务生效。

# vim /usr/local/php/etc/php.ini

extension="/usr/local/php/lib/php/extensions/no-debug-zts-20160303/redis.so"

# systemctl restart nginx
# systemctl restart php-fpm

4.是否安装phpRedis成功,可以通过PHP探针进行测试。

<?phpinfo();?>

将上述代码保存为phpinfo.php上传到网站根目录进行访问,可查看Redis&Session扩展模块的支持。

redis
Redis Support enabled

Redis Version 3.1.2

Available serializers php

session
Session Support enabled

Registered save handlers  files user redis rediscluster

Registered serializer handlers php_serialize php php_binary

至此phpRedis的安装配置已经完成,希望对你有帮助。