作为国内首家推出可编程CDN服务的专业云服务商,优派云利用CDN边缘网络的规模和性能优势,让客户自定义编写规则,满足常见的业务场景。为了保证边缘重定向、请求限速、自定义错误页面、访问防盗链控制、HTTP头管理等这些源数据能够快速同步到边缘节点服务器,经过比较多种方案,而排云在2014年初开始使用Redis2.8版本作为数据同步方案,原结构如下:在继续讲Redis的改进之前,我们需要了解一下技术债。这里所说的技术债指的是技术债。通常,为了加速软件开发,开发人员可能会在应该采用最佳解决方案的时候做出妥协,转而采用能够在短期内加速软件开发的解决方案。而且这种方案给自己带来了日后额外的开发负担。虽然这种期权在当前看来是有利的,但在未来是必须要偿还的,就像债务一样,所以称为技术债。而我们上面提到的解决方案埋下了技术债的引入。虽然在过去几年发挥了重要作用,但架构上的短板也很明显,而且随着边缘服务器数量和同步数据量的增加,再加上服务器硬件老化等原因,造成了很多问题。例如下面的问题:出于安全考虑,Redis之间的通信数据需要加密,但是Redis本身不支持SSL加密。因此,所有边缘服务器都必须是通过Stunnel套接字的中转服务器。但在实际工作情况下,stunnel的性能不足,导致服务器CPU负载过高。Redis的数据主从都是持久连接,尽量保持同源同步。因此,早期的边缘服务器都是通过域名解析来获取源服务器的IP地址。这样做的优点是实现和部署简单,缺点是DNS无法获知后端服务器的处理能力,导致各台机器长连接负载不均衡。而且,后端服务失败后,无法自动处理DNS。即使及时切换解析DNS,由于TTL生效前的真空期,数据也会有所不同,所以旧数据只能应急使用。由于历史原因,大部分edgeRedis版本都是2.x低版本,低版本只能通过sync实现全同步。因此,中转服务器和主服务器的异常会对整个网络造成雪崩效应,导致同步阻塞,无法快速将元数据同步到边缘。因为早期Redis只有主从模式,并没有实现哨兵和集群改造。所以现在主服务器变成了单点风险,很容易在源头造成重大故障。由于之前妥协带来的问题和副作用,我们现在不得不花费额外的时间和精力进行重构,将架构改进到最佳实现。我们将改造过程分为几个步骤:加强SSL的安全保护,尽可能升级到最新稳定版本的OpenSSL。SSL可能是大家接触比较多的互联网安全协议之一。一般网站地址以“https://”开头,采用SSL安全协议。OpenSSL是SSL的开源实现,用于实现网络通信的高强度加密,现在广泛应用于各种网络应用中。如此重要的项目多年来一直资金不足、人手不足,大部分工作只能由少数黑客和爱好者、志愿者来完成。好在现在已经纳入了Linux基金会的资助对象,但还是有新的漏洞不断暴露出来,需要及时关注和跟进。参考最新的OpenSSL漏洞风险等级报告:鉴于RC4算法存在太多安全漏洞,建议在编译时选择禁用。使用最新的stunnel版本优化性能,基于安全的OpenSSL依赖库,支持TLSv1.2+如下图红框可以看出,stunnel在某些算法下性能最强,所以在配置文件中推荐先使用:./configure--prefix=/opt/stunnel--with-ssl=/opt/openssl看看推荐配置中的优化选项:verify=3sslVersionMax=TLSv1.3sslVersionMin=TLSv1。2options=NO_SSLv2options=NO_SSLv3.......ciphers=ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4:!DH:!DHE可以通过AsiaTrustworthy网站做HTTPS信任等级检测和验证。编译最新稳定版Redis-6.2.x,功能强大,功能丰富,无需依赖高版本的GCCRedis6.2。与7.0相比,7.0版本的功能肯定更加强大。Redis7.0包括几乎每个方面的增量改进,最显着的是Redis函数、ACLv2、命令自省和ShardedPub/Sub。7.0版增加了近50个新命令和选项来支持这种演变并扩展Redis的现有功能。但是虽然Redis7.0更加强大,但是考虑到对Redis原有代码的全面兼容以及生产环境的稳定性,我们最终还是选择了Redis6.2。因为Redis6.2有足够的优势和强大的功能,能够更好的满足我们生产环境的要求,比如:多线程IO(ThreadedI/O),很多新的模块(modules)API更好的过期周期(expirecycle)支持SSLACLs权限控制RESP3协议客户端缓存(Clientsidecaching)disklesscopy&PSYNC2Redis-benchmark支持集群Redis-cli优化,重写Systemd支持Redis集群代理随Redis6一起发布(但在不同的repo中)RDB更快负载分配更好SRANDMEMBER和类似命令STRALGO命令更容易使用Redis命令withtimeout突出PSYNC2的特性,这也是我们架构改进和升级的关键特性之一。在Redis集群实际生产运行中,实例维护重启和主实例故障转移(如集群故障转移)操作比较常见(如实例升级、重命名命令、释放实例内存碎片等).).在Redis4.0之前,这种维护处理Redis会完全重新同步,对性能敏感的服务造成少量损害。PSYNC2主要是让Redis在slave实例重启和master实例故障转移场景下使用部分重同步。直接下载源码编译:#makeBUILD_TLS=no推荐配置,加入如下选项增强性能:io-threads-do-readsyesio-threads8aof-use-rdb-preambleyes在我们的测试过程中,我们发现Redis+TLS有几个问题:Redis开启TLS后,性能下降30%。Redis对OpenSSL有很强的依赖性。考虑到以往OpenSSL的高危漏洞,如果要持续修复漏洞,需要重新编译Redis,运维更新成本高。Redis升级后,需要重新同步数据,增加了故障或停产的概率。因此,我们决定使用第三方程序stunnel来加强安全性,方便升级和修复漏洞。不影响后端连接,保证Redis的连续性和稳定性。基于APISIX+TLS托管,使用TCP哈希一致性进行负载均衡替代DNS轮询,性能可圈可点。APISIX使用TCP代理,直接配置后即可使用。与Redis改造关系不大,直接略过,不过大家可以直接看一下改造后的连接数统计截图。从APISIX的实际连接数可以看出,负载被平均分配到不同的后端,边缘服务器的重启也使用PSYNC2进行快速增量同步。使用Redis-shake进行定制化数据同步在架构改进的过程中,我们还看了工具redis-shake,它是阿里云Redis&MongoDB团队开源的Redis数据同步工具。支持分析、恢复、备份、同步四种功能。下面给大家介绍一下同步sync:restorerestore:将RDB文件恢复到目标Redis数据库。备份转储:通过RDB文件备份源Redis的全量数据。解析decode:读取rdb文件,解析成json格式存储。同步sync:支持源Redis和目的Redis之间的数据同步,支持全量和增量数据迁移。同步rump:支持源Redis和目的Redis之间的数据同步,只支持全量迁移。使用scan和restore命令进行迁移,支持不同云厂商不同Redis版本的迁移。我们原来有一个从源码修改过来的Redis,只同步了需要的空间。虽然好用,但还是需要在新的代码上重新编译,但是原来的负责人已经找不到了。这也是很多年久失修的项目的通病,但是通过redis-shake等开源工具,只要简单的通过它进行配置,就可以实现我们想要的功能:-filter。db.whitelist/blacklist-filter.key.whitelist/blacklist-filter.command.whitelist/blacklist目前的架构和未来展望在目前的架构中,我们在原有三层架构的基础上,对三层架构进行了拆分和强化:DNS层解析到VIP,VIP使用BGP/OSPF的动态网关路由协议,对应后一组服务器集群服务。负载均衡层:使用“apisix”+“tls1.2+”+“tcphash一致性连接”来均衡Redis的主从连接和failover。边缘CDN节点利用Redis高版本带来的技术红利,psync增量同步,stunnel+tls1.2实现加密传输。下一阶段,我们会继续将数据中心的Redismaster改造为Redissentinel模式(考虑到需要修改程序代码以兼容sentinel模式,第一阶段先不实现,一切为了生产环境的稳定性)。参考文档:如何查看网站的TLS版本:https://wentao.org/post/2020-...Redis特性复制增强版PSYNC2:https://www.modb.pro/db/79478方便了解Redis架构模式详解:https://www.cnblogs.com/mrhel...推荐阅读【实用干货】做好这16个优化,让你的Linux操作系统焕然一新Golang通用设计模式单例图案
