查看: 1697|回复: 0

[PHP实例] PHP 在redis-sentinel模式下的使用总结

发表于 2017-9-20 08:00:00
句号论坛

近期公司所用项目的缓存想要由memcache迁移到redis,运维给配置的redis使用模式是sentinel(即哨兵模式的),这种模式之前没用过,在此记录一下。

简单介绍下Redis-sentinel:
Redis-sentinel是Redis实例的监控管理、通知和实例失效备援服务,是Redis集群的管理工具。在一般的分布式中心节点数据库中,Redis-sentinel的作用是中心节点的工作,监控各个其他节点的工作情况并且进行故障恢复,来提高集群的高可用性
(简介来自http://www.searchdatabase.com...)

我自己的理解就是,假如有a,b,c 3台可用的redis服务器,其中a为主服务器,b,c为从服务器。
在sentinel模式下如果a出现问题,可以自动将a服务器拿掉或者降级为从服务器,然后从b和c中根据一定策略选择一台升级为主服务器,之后a恢复后作为从服务器使用,避免了了由于某台服务器出现问题时影响整个redis服务。

redis-sentinel模式对redis服务无疑是一个很好的支持,但是在开发人员使用时会稍微麻烦一些。因为可能更常用的模式就是直接在程序中写好一个配置文件,redis主从库都是确定的,程序读取配置文件进行redis操作。假如主库出现问题,必须手动修改配置文件才能继续正常使用。而如果发现的比较晚可能会造成不必要的损失。

而在sentinel模式下需要程序动态获取主从库的ip,即使某台redis服务出现问题,也不会影响到程序,这样就避免了手动修改配置的问题。而关键问题其实就是动态获取主从库的ip,端口等信息了。
在网上查相关资料,大部分都是讲解如何配置sentinel服务,而php对应使用方法不太多。看了官方redis-sentinel文档后了解到获取sentinel信息是有对应API的,只不过是一些原生命令。

而php-redis库是有支持原生命令的方法的,如下:

  1. /*
  2. * Send arbitrary things to the redis server.
  3. * @param string $command Required command to send to the server.
  4. * @param mixed ...$arguments Optional variable amount of arguments to send to the server.
  5. * @return mixed
  6. * @example
  7. * <pre>
  8. * $redis->rawCommand('SET', 'key', 'value'); // bool(true)
  9. * $redis->rawCommand('GET", 'key'); // string(5) "value"
  10. * </pre>
  11. */
  12. public function rawCommand( $command, $arguments ) {}
复制代码

而在开发使用大致过程如下
1、根据运维给的sentinel配置信息连接sentinel,获得需要的信息(注意:此处是sentinel服务的配置信息,和redis的并不一致)。配置信息(IP,PORT)会有多个,每个sentinel返回的redis主从配置信息是一致的,所以进行操作时使用其中一台服务返回的信息即可。

  1. //初始化redis对象
  2. $redis = new Redis();
  3. //连接sentinel服务 host为ip,port为端口
  4. $redis->connect($host, $port);
  5. //可能用到的部分命令,其他可以去官方文档查看
  6. //获取主库列表及其状态信息
  7. $result = $redis->rawCommand('SENTINEL', 'masters');
  8. //根据所配置的主库redis名称获取对应的信息
  9. //master_name应该由运维告知(也可以由上一步的信息中获取)
  10. $result = $redis->rawCommand('SENTINEL', 'master', $master_name);
  11. //根据所配置的主库redis名称获取其对应从库列表及其信息
  12. $result = redis->rawCommand('SENTINEL', 'slaves', $master_name);
  13. //获取特定名称的redis主库地址
  14. $result = $redis->rawCommand('SENTINEL', 'get-master-addr-by-name', $master_name)
  15. //这个方法可以将以上sentinel返回的信息解析为数组
  16. function parseArrayResult(array $data)
  17. {
  18. $result = array();
  19. $count = count($data);
  20. for ($i = 0; $i < $count;) {
  21. $record = $data[$i];
  22. if (is_array($record)) {
  23. $result[] = parseArrayResult($record);
  24. $i++;
  25. } else {
  26. $result[$record] = $data[$i + 1];
  27. $i += 2;
  28. }
  29. }
  30. return $result;
  31. }
复制代码

2、通过以上操作已经可以获取到redis主从库的信息,redis密码是固定的,自己写好就OK。之后就可以按照单例模式去使用redis了,注意操作时主从分离。

以上只是一个大体的使用过程,不同情况可能有所调整。

已上只是简单说了下php程序如何去使用这种模式,具体工作原理和配置请移步
https://segmentfault.com/a/11...
https://segmentfault.com/a/11...



太阳http代理AD
回复

使用道具 举报

关闭

站长推荐上一条 /1 下一条