专栏首页aoho求索高性能消息中间件 NSQ 解析-窥探 nsq 设计思路(一)

高性能消息中间件 NSQ 解析-窥探 nsq 设计思路(一)

我们在前面介绍了 nsq 的相关概念以及 nsq 的安装与应用以及 nsqd 的实现原理、nsqlookupd 的实现细节。

本文将会介绍 nsq 在设计方面的一些思路。

设计概述

从源码可以看到,nsqd 的作用就是实际工作的组件,生产者 producer、消费者 consumer 利用 nsqlookupd 获取最新可用的节点,当连接上对应的 Topic/Channel 后,将消息 message 发送到客户端进行消费,处理成功则 FIN(finish),或失败/超时后重新放回队列 REQ(requeue),待下一次再消费处理。nsqlookupd 的作用就是管理 nsqd 节点的认证、注册、注销、心跳检测,动态维护分布式集群中最新可用的 nsqd 节点列表供客户端取用。

在可靠性、有序性方便, nsq 保证消息至少被投递消费一次(幂等消费),当某个 nsqd 节点出现故障时,极端情况下内存里面的消息还未来得及存入磁盘,这部分消息将丢失;通过分布式多个 consumer 消费,会因为消息处理时长、网络延迟等导致消息重排,再次消费顺序与写入顺序不一致,因此在高可靠性、顺序性方面略存在不足,应根据具体的业务场景进行取舍。

源代码实现逻辑清晰明了,源码中使用了很多读写锁 RWMutex、原子值 atomic.Value、interface 接口复用、自定义通信协议 protocol、http-decorator装饰器、goroutine/channel 协程间并发通信,优先从内存( msqChan )存取消息,从而保证了高可用、高吞吐量的应用能力。快速高效的节点配置与扩展,配合容器云编排技术,可以高效实现集群的 scale 化。

下面我们一起来看下其中实现的精巧之处。

锁与原子操作 RWMutex/atomic.Value

从下面的代码中可以看到,当需要获取一个 topic 的时候,先用读锁去读(此时如果有写锁将被阻塞),若存在则直接返回,若不存在则使用写锁新建一个;另外,使用 atomic.Value 进行结构体某些字段的并发存取值,保证原子性。

func (n *NSQD) GetTopic(topicName string) *Topic {
  // most likely, we already have this topic, so try read lock first.
  n.RLock()
  t, ok := n.topicMap[topicName]
  n.RUnlock()
  if ok {
    return t
  }

  n.Lock()

  t, ok = n.topicMap[topicName]
  if ok {
    n.Unlock()
    return t
  }
  deleteCallback := func(t *Topic) {
    n.DeleteExistingTopic(t.name)
  }
  t = NewTopic(topicName, &context{n}, deleteCallback)
  n.topicMap[topicName] = t

  n.Unlock()
}

消息多路分发与负载均衡

Topic 和 Channel 都没有预先配置。Topic 由第一次发布消息到命名的 Topic 或第一次通过订阅一个命名 Topic 来创建。Channel 被第一次订阅到指定的 Channel 创建。Topic 和 Channel 的所有缓冲的数据相互独立,防止缓慢消费者造成对其他 Channel 的积压(同样适用于 Topic 级别)。

多路分发 - producer 会同时连上 nsq 集群中所有 nsqd 节点,当然这些节点的地址是在初始化时,通过外界传递进去;当发布消息时,producer 会随机选择一个 nsqd 节点发布某个 Topic 的消息;consumer 在订阅 subscribe 某个Topic/Channel时,会首先连上 nsqlookupd 获取最新可用的 nsqd 节点,然后通过 TCP 长连接方式连上所有发布了指定 Topic 的 producer 节点,并在本地用 tornado 轮询每个连接,当某个连接有可读事件时,即有消息达到,处理即可。

负载均衡 - 当向某个 Topic 发布一个消息时,该消息会被复制到所有的 Channel,如果 Channel 只有一个客户端,那么 Channel 就将消息投递给这个客户端;如果 Channel 的客户端不止一个,那么 Channel 将把消息随机投递给任何一个客户端,这也可以看做是客户端的负载均衡

小结

本文主要介绍 nsq 的部分功能设计思路。除了我所介绍的锁与原子操作、消息多路分发,还有诸如队列设计中的优先级队列以及延时队列等。将会在下一篇文章继续介绍其他设计实现的细节。

本文分享自微信公众号 - aoho求索(aohoBlog),作者:aoho

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2021-04-21

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 高性能消息中间件 nsq 解析-介绍

    随着互联网技术在各行各业的应用高速普及与发展,各层应用之间调用关系越来越复杂,架构、开发、运维成本越来越高,高内聚、低耦合、可扩展、高可用已成为了行业需求。

    aoho求索
  • How we redesigned the NSQ- 其他特性及未来计划

    在系列文章前面几篇中,介绍了 NSQ 改造的过程和几个基础特性,本文中我们继续介绍几个高级特性及其使用场景,这些都是结合有赞业务场景总结提炼出来的重要功能。

    有赞coder
  • 高性能消息中间件 NSQ 解析-应用实践

    Nsq 是用 Go 语言开发的轻量级的分布式消息队列,适合小型项目使用、用来学习消息队列实现原理,对于学习 Go channel的原理和用法,以及如何用 Go ...

    aoho求索
  • nsq(有赞分支)、kafka、rocketMq 架构浅析

    消息队列是分布式系统中重要的中间件,在实现系统高性能,高可用,可伸缩性和最终一致性架构框架中扮演着重要角色。是大型分布式系统不可缺少的核心中间件之一。

    有赞coder
  • Go之NSQ简介,原理和使用

    参考上图利用消息队列把业务流程中的非关键流程异步化, 从而显著降低业务请求的响应时间

    常见_youmen
  • golang-nsq系列(四)--源码解析总结篇

    随着互联网技术在各行各业的应用高速普及与发展,各层应用之间调用关系越来越复杂,架构、开发、运维成本越来越高,高内聚、低耦合、可扩展、高可用已成为了行业需求。

    astraw99
  • 剖析nsq消息队列(一) 简介及去中心化实现原理

    分布式消息队列nsq,简单易用,去中心化的设计使nsq更健壮,nsq充分利用了go语言的goroutine和channel来实现的消息处理,代码量也不大,读不了...

    lpxxn
  • 高性能消息中间件 NSQ 解析-nsqd 的实现介绍

    我们在前面介绍了 nsq 的相关概念以及 nsq 的安装与应用。从本篇开始将会结合源码介绍 nsq 的实现细节。

    aoho求索
  • NSQ:分布式的实时消息平台--简介

    源码下载地址: https://github.com/bitly/nsq NSQ是一个基于Go语言的分布式实时消息平台,它基于MIT开源协议发布,代码托管在Gi...

    李海彬
  • NSQ:分布式的实时消息平台--简介

    源码下载地址: https://github.com/bitly/nsq NSQ是一个基于Go语言的分布式实时消息平台,它基于MIT开源协议发布,代码托管在Gi...

    李海彬
  • NSQ:分布式的实时消息平台--简介

    源码下载地址: https://github.com/bitly/nsq NSQ是一个基于Go语言的分布式实时消息平台,它基于MIT开源协议发布,代码托管在Gi...

    李海彬
  • 有赞NSQ多集群多机房设计

    从有赞双机房开始到金融云架构,针对业务方在多机房的应该部署以及消息发送订阅需求,需要 NSQ 针对双机房以及多机房部署提供消息发送与订阅服务。本文主要介绍了 N...

    用户1278550
  • How we redesign the NSQ-NSQ重塑之客户端

    有赞的自研版 NSQ 在高可用性以及负载均衡方面进行了改造,自研版的 nsqd 中引入了数据分区以及副本,副本保存在不同的 nsqd 上,达到容灾目的。此外,自...

    有赞coder
  • NSQ深入与实践

    1. 介绍 最近在研究一些消息中间件,常用的MQ如RabbitMQ,ActiveMQ,Kafka等。NSQ是一个基于Go语言的分布式实时消息平台,它基于MIT开...

    aoho求索
  • 高性能消息中间件 NSQ 解析-nsqlookupd 实现细节介绍

    我们在前面介绍了 nsq 的相关概念以及 nsq 的安装与应用以及 nsqd 的实现原理。你可以翻看前面的文章熟悉 nsq 相关的基础知识。从本篇将会结合源码介...

    aoho求索
  • 消息队列 NSQ

    在谈到消息队列时,除了 Kafka、RabbitMQ、RocketMQ、ActiveMQ 等等之外,我希望你多了解一下 NSQ,之前已经写过一篇文章 《 NSQ...

    凌虚
  • 基于 RocketMQ 的同城双活架构在美菜网的挑战与实践

    本文整理自李样兵在北京站 RocketMQ meetup分享美菜网使用 RocketMQ 过程中的一些心得和经验,偏重于实践。

    用户1564362
  • NSQ 概述

    2、nsqlookupd:管理拓扑信息,其实就是围绕 nsqd 的发现服务,因为其存储了 nsqd 节点的注册信息,所以通过它就可以查询到指定 topic 主题...

    凌虚
  • spring整合各种中间件(RocketMQ、kafka、RabbitMQ、ActiveMQ、ZeroMQ、TubeMQ)NSQ

    上文:spring整合各种中间件(RocketMQ、kafka、RabbitMQ、TubeMQ、NSQ)-腾讯开源【TubeMQ】

    逍遥壮士

扫码关注云+社区

领取腾讯云代金券