金融用户中心架构
本文使用 4 + 1 views 描述架构,希望能帮助自己理解项目本身。
1 场景
金融业务有 5000万+ 用户,理财、信贷业务线都需要访问用户数据,如果各自维护用户表,数据割裂,所以有了金融用户中心,解决用户信息复用问题。
该项目数据量日增近万,峰时QPS 4000+。
2 逻辑
架构图:client、DNS、防火墙、NAT、内网vip、keepalive、Nginx、外部网关、金融用户网关、金融用户中心。
核心表是用户表,单表数据 5000万+,没有分表,但作为维护工作的一部分,做了竖向分库,将账户逻辑剥离。
3 过程
查询接口,使用 Dubbo、Redis,第一次查询后就缓存起来,客户端直接查询缓存。
登录接口,使用 Dubbo,因为 Dubbo协议头才16字节,Http协议头好说32字节,负载均衡 Random。
注册接口,适用 Dubbo,支持 Redis、数据库 生成 userId,号段分配。
更新接口,使用 Kafka,PULL模型下 consumer 按照自己的负载拉取数据。
4 开发
项目分为 client、service 两部分,业务方接入只需要引入 jar 包即可。
使用 Dubbo 做服务治理,是因为项目的定位是中台服务,不直接面向公网流量。
请求的特点是高并发、小数据量(小于50K,复杂pojo场景),内网是万兆网络,拥塞控制的需求小,更加适合使用 Dubbo 协议,来保证 throught、RT。
5 物理
部署了11个实例,铜牛机房5个,马驹桥机房5个,无锡机房1个,两地三中心。
单机QPS 1000,单边5个实例就可以满足 4000+ QPS,可以满足一个机房断电情况下的高可用。
6 思考与展望
怎么做的脱敏
cipher = AES256(PBKDF2(salt + SHA256(plain)))
SHA256
不能使用 MD5、SHA-1,提前哈希,避免加盐后,被 PBKDF2 截断损失信息熵
slat
使用 Java.security.SecureRandom,使彩虹表失效
PBKDF2
计算过程占用内存少
AES256
pepper 保存在 JVM 参数
无锡只读机房的主从同步延迟
半同步复制
主库收到至少一个从库的 ack 就认为写操作完成。没有解决延迟问题。
全同步复制
主库写入binlog 后强制同步从库,收到所有从库的 ack 后才返回给客户端。北京、无锡的网络延迟在 100~200 ms,强一致性是一个很昂贵的操作。
北京两个机房同时宕机的灾难概率很低,所以这个场景只做一个有损的展示,并发公告。
5000万大表,怎么做分表
- 目前用户量 5000 万,一年新增365万,预估40年后数据量达2亿
- 根据 userId 查询最多,用 userId 作为 sharding key
- 手机号、邮箱查询较多,需要考虑 非sharding key 查询的效率
- 包含敏感信息,不能使用数仓、ES 等查询引擎
由于 userId 是严格单调递增,最低位在 0 ~ 9 区间分布均衡。
分10片,多线程扫表查询,生产环境线程池可以开 10+ 个连接,那么非sharding key 的效率也不会差。
如果还是觉得性能不够用,可以给10张表分别创建一个布隆过滤器,不幸遇到假阳性,查询的成本也很低,真阴性就直接不查这一张表。
每片2000万数据,InnoDB 主键索引可以维持在3层,保证 sharding key 的查询效率。