论大数据仓库的事务处理之法
李万鸿2020-10-25
这是一个大数据时代,几乎所有的好产品都离不开大数据的支持,人工智能更是如此。那么,建立数据仓库并使用其中的大数据有何困难呢?那就是事务问题,大数据一般是OLAP,而非OLTP,不具备事务管理功能,但实际使用时存在实时更新数据何查询数据的场景,因此,事务是必不可少的。这个给出一个简单的办法加以解决。
一.加锁原理和方法
Reids的redLock可以提供分布式锁,可以用来简单巧妙解决大数据的事务问题。对基于HIve、Clickhouse等大数据仓库,如果同时读写,可以采用RedLock进行事务控制。RedLock对某个操作提供分布式锁,对SQL语句中的执行加锁,如果写如数据库时,就不让读取数据,反之依然。
对于事务要求不高的场景来说,这是够用的,毕竟,大数据仓库不存在过于频繁的写入,大多是读取数据,所以这个方案是够用的。
举个例子,当根据数据库log实时ETL某个数据后,就需要对数据仓库DW进行更新,并更新DM主体数据库,而此时业务应用正在读取DM或DW的数据,为此,可以在更新写入DW、DM时加个锁,完毕后删除锁,读取数据时首先取锁,如果可以获取,就读数据,否则就等待,直到写入程序删除锁,才能获取锁,并完成读取,然后删除锁。写入也一样,需要先获取锁才能完成写入,否则需要等待读取完成并删除了锁,才可以拿到锁并进行写入,完成后删除锁,让其他程序可以写入或读取数据。
二.关键代码
@Slf4j
public class RedLockDemo {
public static void main(String[] args) {
//连接redis
Config config = new Config();
config.useSingleServer().setAddress("redis://127.0.0.1:6379");
RedissonClient redisson = Redisson.create(config);
log.info("连接Redis");
//1.定义锁
RLock lock = redisson.getLock("myTest001");
try {
//尝试加锁的超时时间
Long timeout = 300L;
//锁过期时间
Long expire = 30L;
//2.获取锁
if (lock.tryLock(timeout, expire, TimeUnit.MILLISECONDS)) {
//2.1.获取锁成功的处理
log.info("加锁成功");
//...do something read or write dw 、 dm
log.info("使用完毕");
} else {
//2.2.获取锁失败的处理
log.info("加锁失败");
log.info("其他处理");
}
} catch (InterruptedException e) {
log.error("尝试获取分布式锁失败", e);
} finally {
//3.释放锁
try {
lock.unlock();
log.info("锁释放成功");
} catch (Exception e) {
//do nothing...
}
}
//关闭连接
redisson.shutdown();
log.info("关闭redis连接");
}
}
三.不需要锁的情况
当没有写入只有读取的时候不需要锁,或只有写入没有读取的时候也不需要锁,为此需要加个判断量Flag,放在Redis,首先设为1表示读,2表示写,程序写或读的时候先取这个变量Flag,如果是读,而flag=1,就不需要锁;else flag=2 ,就需要拿锁。写的时候与此类似,如果是写,而flag=2,就不需要锁;else flag=1 ,就需要拿锁。
这样可以减少用锁,提高效率。
总之,大数据仓库的事务是不能忽视的,加RedLock锁是一个简单巧妙的解决办法,可以一试。