谷歌保持技术竞争力的秘诀
|
有了这个队列,生产者就只需要关注生产,而不用管消费者的消费行为,更不用等待消费者线程执行完;消费者也只管消费,不用管生产者是怎么生产的,更不用等着生产者生产。 所以该模型实现了生产者和消费者之间的解藕和异步。 什么是异步呢? 比如说你和你女朋友打电话,就得等她接了电话你们才能说话,这是同步。 但是如果你跟她发微信,并不需要等她回复,她也不需要立刻回复,而是等她有空了再回,这就是异步。 但是呢,生产者和消费者之间也不能完全没有联系的。
所以它们之间还需要有协作,最经典的就是使用 Object 类里自带的 wait() 和 notify() 或者 notifyAll() 的消息通知机制。
上述描述中的等着,其实就是用 wait() 来实现的; 生产者 - 消费者模型 Producer-consumer problem 是一个非常经典的多线程并发协作的模型,在分布式系统里非常常见。也是面试中无论中美大厂都非常爱考的一个问题,对应届生问的要少一些,但是对于有工作经验的工程师来说,非常爱考。 这个问题有非常多的版本和解决方式,在本文我重点是和大家壹齐理清思路,由浅入深的思考问题,保证大家看完了都能有所收获。 问题背景 简单来说,这个模型是由两类线程构成:
这里阿粉使用 Docker 部署 Redis,性能可能会稍差。 SCAN 原理 最后我们来看下第三个问题,为什么scan 指令就没有问题? 这是因为 scan命令采用一种黑科技-「基于游标的迭代器」。 每次调用 scan 命令,Redis 都会向用户返回一个新的游标以及一定数量的 key。下次再想继续获取剩余的 key,需要将这个游标传入 scan 命令, 以此来延续之前的迭代过程。 简单来讲,scan 命令使用分页查询 redis 。 下面是一个 scan 命令的迭代过程示例: scan 命令使用游标这种方式,巧妙将一次全量查询拆分成多次,降低查询复杂度。 虽然 scan 命令时间复杂度与 keys一样,都是 「O(N)」,但是由于 scan 命令只需要返回少量的 key,所以执行速度会很快。 最后,虽然scan 命令解决 keys不足,但是同时也引入其他一些缺陷:
以上这些缺陷,在我们开发中需要考虑这种情况。 除了 scan以外,redis 还有其他几个用于增量迭代命令:
总结 Redis 使用单线程执行操作命令,所有客户端发送过来命令,Redis 都会现放入队列,然后从队列中顺序取出执行相应的命令。 如果任一任务执行过慢,就会影响队列中其他任务的,这样在外部客户端看来,迟迟拿不到 Redis 的响应,看起来就很阻塞了一样。
所以不要在生产执行 keys、smembers、hgetall、zrange这类可能造成阻塞的指令,如果真需要执行,可以使用相应的scan 命令渐进式遍历,可以有效防止阻塞问题。 (编辑:怀化站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |

