Guava Cache中如何处理脏数据
how to deal with dirty data in Guava Cache
我使用 Guava Cache
来缓存我的数据。缓存中的数据如果几分钟没有被使用,就会被清理。
如果我修改了我的数据,我会更新缓存中的数据,并标记数据"dirty"(因为它被修改了,并且与数据库中的数据不同)。
每隔 5 分钟,我会将 "dirty" 数据推送到数据库(即更新数据库中的数据)。
问题是,有一个"dirty"数据A,在数据A被push到数据库之前,数据A已经被清理了,然后我会丢失"dirty"数据A。
所以,我在Guava Cache
中添加一个RemovalListener
,当数据被清理后,RemovalListener
会通知我,我会回调函数。在函数中,我尝试将数据放回缓存。但是在多线程环境下,它不能保证数据的正确性。
例如:
1)缓存:清理数据A
2)线程1:获取数据A,缓存中的数据A已被清理,所以缓存将从database.And数据库中的数据A不是最新的获取数据A。所以线程 1 得到了一个不正确的数据 A.
3)缓存:运行 RemovalListener 回调。
那么,如何处理脏数据,保证在多线程时数据始终正确?谢谢!
一种可能的解决方案是将脏数据写入RemovalListener
。如果这是同步完成的,则同一条目上的其他操作将被阻止,并且不会出现不一致的状态。根据数据库的延迟,这可能还会影响缓存上的其他操作,请参阅 Guavas 文档中的警告。
一般来说,你喜欢做的就是所谓的"write behind cache"。有内置此功能的缓存产品。看看现有的解决方案。
我使用 Guava Cache
来缓存我的数据。缓存中的数据如果几分钟没有被使用,就会被清理。
如果我修改了我的数据,我会更新缓存中的数据,并标记数据"dirty"(因为它被修改了,并且与数据库中的数据不同)。 每隔 5 分钟,我会将 "dirty" 数据推送到数据库(即更新数据库中的数据)。
问题是,有一个"dirty"数据A,在数据A被push到数据库之前,数据A已经被清理了,然后我会丢失"dirty"数据A。
所以,我在Guava Cache
中添加一个RemovalListener
,当数据被清理后,RemovalListener
会通知我,我会回调函数。在函数中,我尝试将数据放回缓存。但是在多线程环境下,它不能保证数据的正确性。
例如:
1)缓存:清理数据A
2)线程1:获取数据A,缓存中的数据A已被清理,所以缓存将从database.And数据库中的数据A不是最新的获取数据A。所以线程 1 得到了一个不正确的数据 A.
3)缓存:运行 RemovalListener 回调。
那么,如何处理脏数据,保证在多线程时数据始终正确?谢谢!
一种可能的解决方案是将脏数据写入RemovalListener
。如果这是同步完成的,则同一条目上的其他操作将被阻止,并且不会出现不一致的状态。根据数据库的延迟,这可能还会影响缓存上的其他操作,请参阅 Guavas 文档中的警告。
一般来说,你喜欢做的就是所谓的"write behind cache"。有内置此功能的缓存产品。看看现有的解决方案。