Ruby 我照着 collectiveidea/audited 改了一套 mongoid 版

kevinyu · May 26, 2021 · Last by kevinyu replied at May 31, 2021 · 532 hits

背景

公司想使用audited 用来作为审计,但是由于日积月累会导致 audits 表非常大。

定时删除此表以及此表的读写都对数据库性能有很大的影响。这个问题我在上家公司也遇到过表里有一亿数据,

运维小哥不知道备份一次就这一个表就有 25G 大,我写脚本删除的时候异常痛苦因为要分批删除,

还要尽量避免间隙锁。所以我和团队师兄商量一下决定采用 mongo 存储日志,

因为这个表只会创建和查询使用 mongo 还挺不错的,双数据库也可以不影响 mysql 主库的性能。

结果查了一下 audited仅仅有一个版本很老的audited-mongo_mapper版本,我们项目使用的是 mongoid

所以我就照着ActiveRecord版本改了一个mongoid版本的audited-mongoid,勉强能用了,有需要的可以试试看。

按步骤创建好核心的模块文件之后,仅需要进行简单的引入就可以实现。

模型引入

模型引入auditedmongo库中会自动创建一个集合model_audit_logs,并设置了日志的保留时间 (需要在mongo中建立索引后生效) ,建立索引后日志会在到期时自动删除,而无需像ActiveRecord版本那样手动删除以减轻对mysql的压力。

class Model < ActiveRecord::Base
  MONGO_EXPIRE_AFTER_SECONDS = 30.days # mongo中日志保留时间
  include Audited # 引入审计模块
  audited  # 调用审计初始化方法
end

audited 方法使用

监控所有字段 (不包含默认忽略字段,例如:created_at updated_at...)

audited

监控单一字段

audited only: :name

监控多个字段

audited only: [:name, :address]

监控除某些字段外的所有字段

audited except: :password

只需要稍作修改即可满足自定义的业务,比如自定义 action 名 (可以存入状态机event+ 国际化即可完善审计日志)

审计流程可以用 redis,可以用队列系统定时处理下无用的脏数据,这样可以保持数据表的实用型,有用数据保存

😀 或者可以建立分区表,写个 task, 定期删表即可。无需改任何方案。

audits 不是有个配置,可以就保存最近的 10 个记录吗

Reply to darksky

对于操作记录都是要保留的,用来排查问题,如果可能肯定是保留的越多越好,但是有限于数据库容量要花钱所以可能部分增长快的表会做定时删除,暂时还没删除,有的记录估计一个月就就有几百万。

我们这边是想都保留但是不想占用 mysql 的性能。

Reply to watsy0007

嗯就是麻烦点,以前就是这么干的。

行我研究下这个感谢

Reply to kevinyu

看到了是这个吧 max_audits,嗯这个挺好的不过我们不是单个对象操作次数多,而是对象太多了,比如订单操作日志,订单量大了即使这里限制了日志还是订单的 N 倍放大。

2021 年了,还有人用 mongodb?

Reply to hooopo

现在推荐啥 DB?😉

Reply to apexy

PostgreSQL

Reply to kevinyu

历史订单多,你也要转移了吧,不应该放在同个库里吧

Good job!

嗯 历史订单 DBA 会操作的

You need to Sign in before reply, if you don't have an account, please Sign up first.