集合运算的过程分析与架构设计

Posted by WGrape的博客 on May 12, 2021

文章内容更新请以 WGrape GitHub博客 : 集合运算的过程分析与架构设计 为准

前言

本文原创,著作权归WGrape所有,未经授权,严禁转载

一、问题背景

对于实时性的集合运算,PHP+Redis架构在小数据量和低并发的场景下还是可行的,一旦数据量和并发上升,这种架构就会暴露出各种问题

  • 网络流量过大,占用带宽过多
  • 运算性能低下,无法快速完成
  • 等等 … …

如何对现有架构升级 ?

二、过程分析

当外部请求通过网络到达时,服务内部会先获取到待计算的数据,经过在内存中的计算,最终处理结果并通过网络返回。

image

在整个过程中,主要分为网络、获取待计算数据、内存计算、处理结果四部分

1、网络

(1) 作用

主要承载业务方请求的接收,响应

image

此外可能还会有请求Redis、Redis和Cache间的同步等操作会使用到网络

(2) 业务协议

优先支持HTTP协议

2、获取待计算数据

(1) 数据源有哪些

可用的数据源主要有Redis和本地Cache

① Redis

如果需要的数据不在Cache中,则通过请求Redis的方式获取数据。但由于请求Redis大量数据时会严重占用带宽,所以必须提供Redis限流模块来解决此问题

image

② 本地Cache

把部分Redis数据以文件或内存Cache的方式,存储至本地,减少每次都请求Redis的网络开销。

但使用Cache会面临数据不一致的问题,那么如何做到数据同步 ?在数据同步时,又如何解决数据竞争问题 ?这些问题都交给数据同步模块解决

image

(2) 什么是待计算数据

数据源中有很多很多数据,但每次集合运算只需要与此次计算有关的数据,这些数据就是待计算数据

(3) 如何筛选待计算数据

由业务方请求中的参数控制决定,如业务方请求参数Key=A&Key2=B,那么此次集合运算中的待计算数据,就是数据源中Key为A和B的两个数据

image

① 数据源中待计算数据的类型

  • 在Redis中 :支持 List / Set / Sorted Set 三种类型,元素为整型数字
  • 在Cache中 :二进制存储、JSON存储、内存变量等

(5) Redis限流模块

业务请求中如果传递了需要计算的数据量(不传递则视为使用默认值),那么系统会对此数据量做评估,做出是否需要限流的决策

image

具体的限流方案是分批获取,如业务要求计算1000万的数据量,则分10次获取数据,每次只获取100万的数据

(6) Cache数据同步模块

先在架构中留下此模块的设计,待一期完成后补充

3、内存计算

(1) 数据载入内存

从基本过程中可知获取待计算数据后,会把数据载入内存中

① 内存中待计算数据的类型

整型Slice

(2) 如何进行集合运算

通过位运算与位向量技术,或使用golang-set实现

4、处理结果

当返回的数据量过大时,需要对返回的数据做压缩(gzip)处理

三、架构设计

1、架构概览

image (6)

2、接入层

使用Nginx + Lua实现高并发、高性能、高可用的服务

3、网络层

主要负责并支持各种协议的网络通信、Gzip压缩

4、控制层

对业务方的请求做解析,包括参数解析,数据量评估,数据源的选择,限流等

5、数据层

提供Cache、Redis两种数据源

6、计算层

把数据载入内存,进行集合运算

7、响应层

对返回结果做加密、压缩等额外的处理操作