银行高并发场景下,数据一致性非常重要,容器云平台如何有效保证承载运行数据的一致性?在高并发时候快速扩容,故障快速恢复且相对简单易用?
收起简单的说,一致性问题应该分为业务一致性和数据一致性两个方面,通常,业务一致性应该由微服务或上层应用保证。
而数据一致性问题如果面对单一应用,应用层面会通过操作系统保证崩溃一致性,存储层面会保证多lun的一致性及复制一致性。例如在某个场景下,数据库的数据文件和日志文件,分别存储在两个lun里,那么通常数据库会通过dependency write保证一定会先写日志再写数据,但是存储down机的瞬间,存储是否能保证日志文件和数据文件两个lun是一致的,这是存储对崩溃一致性的处理能力。同时,如果把两个卷分别通过async/sync复制到远端存储,那么就会涉及目标lun的复制一致性,即必须保证在某个时刻,哪怕发生了某种灾难,远端的两个卷里的数据也是一致的。
在容器场景里,这两种一致性问题的处理方式是不一样的:
1. 对于业务,一般在微服务领域会处理分布式一致性问题,这点已经通过开源方案做得很好了,在灵雀云实施的客户里,也有不少客户需要这些方案;
2. 对于数据一致性,这点上,单一容器内并不会有额外的处理,OS对崩溃一致性的处理并不会更好或坏,而存储侧的能力还需要存储来解决。
但是一个相关的话题是应用状态保留的问题,或者我自己命名为“重启一致性“,毕竟容器领域,重启是常见现象,也可以拿出来分享:
容器平台采用 K8s的statefulset工作负载来保证平台承载的应用数据的一致性,稳定的持久化存储,即Pod重新调度后还是能访问到相同的持久化数据,基于PVC来实现。
statefulset 工作负载有以下特性:
1. 稳定的网络标志:即Pod重新调度后其PodName和HostName不变,基于Headless Service(即没有Cluster IP的Service)来实现;
2. 有序部署,有序扩展:即Pod是有顺序的,在部署或者扩展的时候要依据定义的顺序依次依次进行(即从0到N-1,在下一个Pod运行之前所有之前的Pod必须都是Running和Ready状态),基于init containers来实现;
3. 有序收缩,有序删除(即从N-1到0):容器云平台一般采用HPA(Horizontal Pod Autoscaler)Pod自动弹性伸缩进行故障快速恢复,可以通过对Pod中运行的容器各项指标(CPU占用、内存占用、网络请求量)的检测,实现对Pod实例个数的动态新增和减少。
现在国内容器云产品在K8s 的工作负载支持方面都做得不错,除此之外,灵雀云在产品中使用K8s的operator技术进行有状态应用的部署、运维等能力,并且提供中间件的容器化服务 RDS 能力,是对数据服务(中间件、数据库)的进一步增强。
针对您刚才提到的高并发时刻快速扩容、故障恢复,这个问题本身是容器平台的优势所在,不管手工还是自动都已经有大量客户实践的案例产生,已经是非常成熟的技术。
另外,上面虽然探讨了数据一致性问题,但是通过存储保证数据一致性并非容器平台的最佳实践,我的建议是: