MST

星途 面试题库

面试题:HBase中RegionObserver类实现数据审计功能

假设你需要在HBase中实现对特定表的所有数据修改操作进行审计,即记录每次数据的修改者、修改时间和修改内容等信息。请阐述如何基于RegionObserver类来实现这一功能,需要详细说明实现的关键步骤和涉及到的主要方法。
19.4万 热度难度
数据库Hbase

知识考点

AI 面试

面试题答案

一键面试

关键步骤

  1. 创建自定义RegionObserver类:继承RegionObserver类,并重写相关方法。
  2. 注册自定义Observer:将自定义的Observer注册到HBase表上。

主要方法

  1. prePut
    • 作用:在Put操作执行前被调用。
    • 实现思路:在此方法中获取修改者信息(如通过当前用户认证信息)、修改时间(使用System.currentTimeMillis())以及修改内容(从Put对象中获取要插入或更新的单元格数据)。然后将这些审计信息写入到审计表中。
    • 示例代码片段
@Override
public void prePut(ObserverContext<RegionCoprocessorEnvironment> e, Put put, WALEdit edit, Durability durability) throws IOException {
    // 获取修改者信息,假设可以从环境中获取当前用户
    String modifier = getCurrentUser(e.getEnvironment());
    long modifyTime = System.currentTimeMillis();
    // 从Put对象中获取修改内容
    List<Cell> cells = put.getFamilyCellMap().values().stream().flatMap(List::stream).collect(Collectors.toList());
    // 将审计信息写入审计表
    writeAuditInfo(modifier, modifyTime, cells);
}
  1. preDelete
    • 作用:在Delete操作执行前被调用。
    • 实现思路:获取修改者、修改时间以及将要删除的内容(从Delete对象获取相关单元格),并将这些审计信息写入审计表。
    • 示例代码片段
@Override
public void preDelete(ObserverContext<RegionCoprocessorEnvironment> e, Delete delete, WALEdit edit, Durability durability) throws IOException {
    String modifier = getCurrentUser(e.getEnvironment());
    long modifyTime = System.currentTimeMillis();
    List<Cell> cells = delete.getFamilyCellMap().values().stream().flatMap(List::stream).collect(Collectors.toList());
    writeAuditInfo(modifier, modifyTime, cells);
}
  1. writeAuditInfo
    • 作用:负责将审计信息写入到专门的审计表中。
    • 实现思路:构建一个Put对象,将审计信息(修改者、修改时间、修改内容)作为单元格数据放入Put对象,然后使用HBase的Table对象将数据写入审计表。
    • 示例代码片段
private void writeAuditInfo(String modifier, long modifyTime, List<Cell> cells) throws IOException {
    Configuration conf = HBaseConfiguration.create();
    Connection connection = ConnectionFactory.createConnection(conf);
    Table auditTable = connection.getTable(TableName.valueOf("audit_table"));
    Put auditPut = new Put(Bytes.toBytes(System.currentTimeMillis()));
    auditPut.addColumn(Bytes.toBytes("info"), Bytes.toBytes("modifier"), Bytes.toBytes(modifier));
    auditPut.addColumn(Bytes.toBytes("info"), Bytes.toBytes("modify_time"), Bytes.toBytes(modifyTime));
    // 将修改内容序列化后写入,这里简单示例,实际可能需更复杂处理
    String content = cells.stream().map(CellUtil::formatCell).collect(Collectors.joining(","));
    auditPut.addColumn(Bytes.toBytes("info"), Bytes.toBytes("content"), Bytes.toBytes(content));
    auditTable.put(auditPut);
    auditTable.close();
    connection.close();
}
  1. getCurrentUser
    • 作用:获取当前执行操作的用户信息。
    • 实现思路:根据具体的HBase环境和认证机制实现,例如在Kerberos认证环境下,可以从当前线程的上下文获取认证用户信息。
    • 示例代码片段(假设简单通过环境变量获取)
private String getCurrentUser(RegionCoprocessorEnvironment environment) {
    return System.getenv("USER");
}

注册Observer

  1. 使用HBase Shell
    • 可以使用alter 'table_name', METHOD => 'table_att','coprocessor'=>'|fully_qualified_classname|priority|arg1=value1,arg2=value2'命令将自定义Observer注册到表上。
  2. 通过Java API
    • 可以通过HBaseAdmin类的addCoprocessor方法来注册Observer。示例代码如下:
Configuration conf = HBaseConfiguration.create();
HBaseAdmin admin = new HBaseAdmin(conf);
CoprocessorDescriptorBuilder coprocessorDescriptor = CoprocessorDescriptorBuilder.newBuilder()
      .setCoprocessorClass(MyAuditObserver.class)
      .setPriority(100)
      .build();
admin.addCoprocessor(TableName.valueOf("table_name"), coprocessorDescriptor);
admin.close();