我们知道,多线程并发访问共享数据的时候,可能会造成并发安全问题,这是由于并发时多个线程相互穿插造成的问题;可以通过加锁,使得多个线程串行执行解决。
当访问的是 redis 中的共享数据时,除了可以通过加锁解决,还可以 使用 lua 脚本 解决。
本文针对 redis 结合 lua 脚本解决多线程并发安全问题,记录下个人的理解。
首先何为原子性 ?原子性 是指操作不可分割,要么全部执行成功,要么全部执行失败,中间不会被打断。
使用 lua 脚本就可以实现一组操作的原子性,这些操作作为一个整体,要么全部执行成功,要么全部执行失败,也就不会存在不同的操作先后执行、多个线程之间相互穿插的情况了。
redis 是一个单线程模型的数据库。redis 虽然可以支持多个客户端的并发连接,但是每个客户端的操作其实是按照顺序进行的。也就是说,如果一个客户端正在执行某个操作,其他客户端需要等待这个操作执行完毕后才能进行操作。
看到这里,应该也就能够明白了。我们把多个操作写成一个 lua 脚本,使其具备原子性,作为一个整体执行。再由于 redis 是单线程模型,不同线程的 lua 脚本是依次执行的。也就是说,只有一个线程原子性的多个操作执行完,下一个线程才可以执行。实际上也是保证了在 redis 内部不同线程操作的串行执行,从而能够解决并发安全问题。
因此,结合 lua 脚本可以实现原子操作,对于需要对多个 key 进行操作的场景,可以把多个操作封装到一个 lua 脚本中,这样就可以保证这些操作的原子性,避免多个线程之间的数据竞争问题,从而保证Redis数据库的数据一致性和可靠性。
如果有帮助的话,可以点个赞支持一下嘛