如何用多个线程顺序读取缓存队列?

我定义了一个数据缓存(ArrayBlockQueue),用多个线程去读取缓存,并将数据写入到数据库中。

现在的问题是这样的:由于缓存中存放的是用户的行为数据,所以入库的时候每个用户各自的数据需要严格按照时间来入库,但多线程下是无法保证这种顺序性的。

思考了一下,想用这种方式来做:队列中不同用户的数据不需要考虑顺序,两个线程随意读取;但一个用户的数据只能由某个特定线程去读取,这样数据进入队列时的时序性就能够保证入库的时序性了。

有没有比较简单的方法来实现呢?

回答:

这其实是一个生产/消费模型中的一个问题: 顺序消费的问题.(假定生产者已将数据按照顺序放入队列)

最开始能想到的方法:

单线程消费, 这样就严格保证了顺序.

但带来的问题是消费速度慢, 特别是这种插入关系型数据库(耗IO)的行为, 这样就会导致队列全满, 从而有可能影响到生产者, 或者是丢失数据, 消耗内存.

可以从两个方面解决:

  • 仍然保持单线程消费, 而提高后端的消费速度, 从题主的case看, 记录的只是用户的行为日志, 很多时候, 日志只需要进行append即可, 即顺序写磁盘, 或者写类似于HBaseLSM tree的数据库.(当然也会带来查询上的问题).

  • 单线程换成多线程, 题注的case中,只关注单个用户的顺序性, 所以可以对用户进行分区(比如简单的hash).

    可以对队列进行分区, 也可以对消费线程进行分区, 从而达到并行的效果.

另外, 从题主的描述来看, 我猜想可能是个 web 应用, 并且使用了内存队列作为操作日志的缓存, 再通过异步线程去写入这些日志.

这里需要注意的是, 如果你的部署结果是 N台web + 前端负载, 那么还需要注意前端负载对用户的路由策略, 如果全局的用户操作日志已经没有顺序了, 那么单机再怎么严格顺序, 也没有意义.

回答:

用户的行为时间可以存到db字段里,db可以帮你按这个字段排序啊

回答:

既然你的用户数据可以分开,那不同的用户数据使用不同的缓存就好了,实现起来最简单。

如果你需要更高的缓存使用率和并行率,那可以在用户的数据中加入用户ID和顺序编号(通过统一的方法生成或直接使用时间戳),就既可以使用多线程处理同一个用户的数据,也可以保证某一个用户的入库顺序了。

回答:

用户ID进行hash到不同的线程就是了。

找了个比较应景的图

以上是 如何用多个线程顺序读取缓存队列? 的全部内容, 来源链接: utcz.com/a/167206.html

回到顶部