审计的有效方式

Efficient way for Auditing

我正在尝试为我的 spring 启动实施审计层 application.I 目前尝试了两种方法。

1) 创建了 1 个审计 table,字段为 user_name、table_name、column_name、old_value、new_value、uuid、event_type.

每当保存任何更改时,填充审计实体并保存它。

优点:

瀑布:


2) 使用 javers 进行审计

优点:

瀑布:


基准

处理具有 20 列(字段)的 table(实体)中的 10 行,

使用方法 1 所用时间:24328 毫秒 => 24 秒

使用方法 2 所用时间:311292 毫秒 => 311 秒(将近 12 次)


3) 没有使用 Hibernate envers,因为创建的 table 数量会很高

有人可以针对上述优缺点提出更好的审计想法吗?我们的目标是,

每个 table 中有 10 到 25 列。

我会采用这种方法:

1) 在低优先级的后台线程中审计

2) 使用带注释的spring AOP 将BU 与AUDITING 分开

3) 每次插入或更新实体时,将完整的 jsonized 对象写入带有 UID 的 NOSQL 数据库文档中;旧值也没有用,因为您可以回溯实体的更改 运行 简单查询

正如您所说,创建审计跟踪的常用方法是应用程序端库,如 envers 或 Javers。这些连接到持久性库中,它们会在数据 table 中维护特定的列("createdBy"、"lastUpdated" 等),and/or 复制得更早将版本记录到某种形式的历史记录 tables.

不过这也有一些缺点:

  • 在历史 tables 中写入记录作为 OLTP 事务的一部分会增加事务中执行语句的数量 -> 可能会导致应用程序的响应时间更长

  • 支持批量更新和删除

  • 无法跟踪直接在数据库中完成的更改

3 步更改数据捕获

  1. 捕获更改数据
  2. 将更改数据转换为目标数据库支持上传的格式
  3. 上传数据到目标数据库

通过数据库触发器更改数据捕获

另一种技术是数据库触发器。他们不会错过任何操作,无论是从应用程序还是数据库本身发出的。 Bulk Statement 也将被处理。 基于触发器的 CDC 的另一个优点是应用程序不会意识到您已经添加了整个审计层。 不利的一面是,在将触发器作为 OLTP 事务的一部分执行时,仍然存在延迟增加的问题。

触发器的替代解决方案(此处为 Postgresql): 使用逻辑复制将数据库更改(解码的 WAL 消息)从主服务器流式传输到使用 WAL 的从服务器,并启用审计触发器以捕获从服务器上复制的 tables 的更改。

通过基于日志的方法更改数据捕获

当利用 transaction log 作为审计源并使用变更数据捕获来检索变更信息并将其发送到消息代理或基于持久日志的系统时,上述问题不存在,例如 Apache Kafka。通常被认为是更改数据捕获的最佳方法,但不是最简单的设置解决方案。

运行 异步,CDC 进程可以在不影响 OLTP 事务的情况下提取更改数据。

只要有数据更改,就会在事务日志中添加一个条目。

在批量操作中更新或删除的每条记录都会有一个日志条目,因此可以为每条记录生成一个更改事件。

仍然是 CDC 如何访问元数据的问题,例如执行数据更改的应用程序用户、他们的 IP 地址、跟踪跨度 ID 或任何类型的 correlationID。

一种方法是使用单独的 table 来存储此元数据。该应用程序可以为每个事务存储一个记录,其中包含一个特定的 table transactionId。数据更改事件将包含链接到更改的 transactionID,因此数据更改事件和元数据记录可以相关联。

显然你没有以正确的方式使用 Javers,你的数字不可靠。也许您正在为每次提交创建新的 Javers 实例?

Javers 与审计工具一样快。 Javers 只是为更改的对象创建快照并将它们插入到数据库中。每个快照一个数据库 record/document。

因此,如果您更改一个对象,通常 Javers 会执行一次 DB 读取以获取其先前的快照,并执行一次 DB 插入以写入新快照。