一次简单的分表实践

作者: spring_coderman | 来源:发表于2019-12-02 15:00 被阅读0次

背景:笔者负责公司内部单点登录系统(inpass)已两年有余,登录服务接入逐渐增多,登录日志逐渐增多。笔者对登录日志也进行了几轮改造和优化,其中涉及到了一次简单的分表操作,特此记录下来。

改造之前的状况(2018.7月调研)

inpass日志表中id采用工具类(SnowflakeIdWorker)自动生成id,但是存在高并发下id重复问题,数据库插入存在主键冲突,导致业务方调用出现异常。同时原有数据库表login_log中数据量已达400w+,统计最近4天的登录日志,平均每天16000条,且有逐渐增多的趋势,因此有必要进行优化。
当时调研了三种方案,如下:

方案1:

将id生成器工具类替换为使用共享服务部提供的ID生成器服务,其他不变。
优点:可快速优化高并发下id重复问题,代码量比较少
缺点:需要增加依赖服务,无法对现有表数据进行拆分优化。

方案2:

重新构建日志表(login_log_new),表字段不变,id改为数据库自增方式。
优点:

  1. 不依赖外部id唯一工具,
  2. 可拆分登录日志,减少原有表数据逐渐增大的问题。
    缺点:
    需要新建表。

方案3:

删除当前日志表(login_log)中3个月之前的数据+方案1.
优点:不需要新建表,
缺点:线上删除大数据量可能会锁表,同时会丢失大量日志数据。
综合考虑,方案2为优。
那上面的方案是否是一劳永逸的呢?
答案是否定的。

我们设想一下,现在的日均日志量已经不是16000+,而是18000+了,
假如以一年为单位,16000365 = 584W条。
18000
365 = 657W条。
数据库是MySQL的,场景是插入多,查询少,比例与插入量差不多,但是如果要查的话,那看下面的sql:
select count(*) from login_log where login_time >='2018-07-24 00:00:00' and login_time <='2018-07-24 23:59:59';
这个sql至少执行了3.8秒。应该是可以优化的。

要查该表的背景

  1. 某员工违规操作,要查日志,什么时间登录的,登录到哪个IP地址。
  2. 某员工最近一个月通过inpass登录系统的日志。
    这种场景非常少,但是在单表这么多数据量的情况下一条sql执行下来估计也需要不少时间。

可以借用分表的设计想法,(分库就不用了哈,没那么多复杂的需求),以年为单位,预先设计3张表login_log_2018(已初始化到线上),login_log_2019(已初始化到线上),login_log_2020(未初始化到线上).
假设每张表存储不超过1KW条数据,以年为单位记,即可满足未来3年内的日志增长量。同时满足所有日志可查。

按上述方案执行之后,到现在已经往login_log_2018表写入了480w登录日志数据了,其实已经到了需要写新表的时候了,此时也接到了需要对inpass进行内审安全合规性的改造,用户需要对登录日志进行查询。新的需求需要对登录过程中的所有操作进行记录,包括修改密码等环节。而原来的登录日志记录仅仅记录登录成功的场景,因此如果再写入数据库就不合适了。

此时需要进行新的改造,由于inpass只是提供单点登录和修改密码的功能,没有查询界面,如果给用户新开列表查询界面也不合适。
经过和领导沟通,有如下操作和方案

  1. 将登录日志以埋点的方式接入公司的日志平台进行上报。
  2. inpass服务端使用线程池异步写日志(不阻塞登录主流程)
  3. 由于接入日志平台之后日志平台可以提供查询界面,所以inpass的改造仅仅在用日志埋点的接入,但是为了保障整个接入过程顺利还进行了双写的操作。
  4. 就是一方面将登录日志上报到日志平台,一方面写入数据库,此时需要新建表,因为新增了几个记录项,不适合在原有表中扩展,新表为login_log_2020.
  5. 第4步的操作也为了保障在接入过程中数据可以冗余保留,如果日志平台确实能满足用户查询需求,我们可以很快下掉写数据库的逻辑。

相关文章

  • 一次简单的分表实践

    背景:笔者负责公司内部单点登录系统(inpass)已两年有余,登录服务接入逐渐增多,登录日志逐渐增多。笔者对登录日...

  • 当业务发展遇上分库分表,事情变得有意思了。。。

    本文来源:crossoverJie 背景 前不久发过两篇关于分表的文章:一次分表踩坑实践的探讨,分表后需要注意的二...

  • 一次难得的分库分表实践

    背景 前不久发过两篇关于分表的文章: 一次分表踩坑实践的探讨 分表后需要注意的二三事 从标题可以看得出来,当时我们...

  • 分库分表实践例子

    背景 前不久发过两篇关于分表的文章: 一次分表踩坑实践的探讨 分表后需要注意的二三事 从标题可以看得出来,当时我们...

  • Jav高级开发订单系统分库分表实践及mycat分表分库的原理你知

    Jav高级开发订单系统分库分表实践及mycat分表分库的原理你知道吗 引言 从字面上简单理解,就是把原本存储于一个...

  • 分库分表实践

    1 3000万数据分库分表方法小结

  • 一次难得的分库分表实践

    先来回顾下整个分库分表的流程如下: 整个过程也很好理解,基本符合大部分公司的一个发展方向。 很少会有业务一开始就会...

  • 分表后需要注意的二三事

    前言 本篇是上一篇《一次分表踩坑实践的探讨》,所以还没看过的朋友建议先看上文。 还是先来简单回顾下上次提到了哪些内...

  • 日常惯例表

    惯例表的注意要点 1. 惯例表不等于计划表 2. 时间长度要注意,第一次:实践的过程≤5分钟,惯例表的施行时间≤3...

  • 一次分表踩坑实践的探讨

    前言 之前不少人问我“能否分享一些分库分表相关的实践”,其实不是我不分享,而是真的经验不多?;和大部分人一样都是停...

网友评论

    本文标题:一次简单的分表实践

    本文链接:https://www.haomeiwen.com/subject/kwxfgctx.html