开发者社区> 问答> 正文

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

我定义了一个数据缓存(ArrayBlockQueue),用多个线程去读取缓存,并将数据写入到数据库中。 现在的问题是这样的:由于缓存中存放的是用户的行为数据,所以入库的时候每个用户各自的数据需要严格按照时间来入库,但多线程下是无法保证这种顺序性的。
思考了一下,想用这种方式来做:队列中不同用户的数据不需要考虑顺序,两个线程随意读取;但一个用户的数据只能由某个特定线程去读取,这样数据进入队列时的时序性就能够保证入库的时序性了。
有没有比较简单的方法来实现呢?

展开
收起
蛮大人123 2016-02-29 17:01:05 3204 0
1 条回答
写回答
取消 提交回答
  • 我说我不帅他们就打我,还说我虚伪

    这其实是一个生产/消费模型中的一个问题: 顺序消费的问题.(假定生产者已将数据按照顺序放入队列)
    最开始能想到的方法:
    单线程消费, 这样就严格保证了顺序.
    但带来的问题是消费速度慢, 特别是这种插入关系型数据库(耗IO)的行为, 这样就会导致队列全满, 从而有可能影响到生产者, 或者是丢失数据, 消耗内存.
    可以从两个方面解决:

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

    单线程换成多线程, 题注的case中,只关注单个用户的顺序性, 所以可以对用户进行分区(比如简单的hash).
    可以对队列进行分区, 也可以对消费线程进行分区, 从而达到并行的效果.
    另外, 从题主的描述来看, 我猜想可能是个 web 应用, 并且使用了内存队列作为操作日志的缓存, 再通过异步线程去写入这些日志.
    这里需要注意的是, 如果你的部署结果是 N台web + 前端负载, 那么还需要注意前端负载对用户的路由策略, 如果全局的用户操作日志已经没有顺序了, 那么单机再怎么严格顺序, 也没有意义.

    2019-07-17 18:50:35
    赞同 展开评论 打赏
问答分类:
问答地址:
问答排行榜
最热
最新

相关电子书

更多
基于英特尔 SSD 的虚拟机缓存解决SSD 立即下载
多IO线程优化版 立即下载
高性能Web架构之缓存体系 立即下载

相关实验场景

更多