How we redesigned the NSQ - NSQ重塑之详细设计

之前的 文章 讲述了我们重塑NSQ的目的和目标, 接下来我们将详细描述下每个功能的具体技术细节. 重构后架构图 首先, 看一下重构后的整体架构图: 原来的几个NSQ组件大部分功能是复用的, 图中新增的就是元数据存储服务-etcd, 以及数据同步和HA处理逻辑. 改造topic queue 为了增加副本和其他特性, 首先需要改造的就是nsq的topic数据写入方式, 要保证数据最终落盘, 才能继续后面的改造. 所以我们第一步重构数据写入逻辑, 这块逻辑本身并不依赖分布式功能, 可以独立重构. 数据落盘 原版的topic写入流程是通过golang里面的chan来做的, 只有超过chan容量之后, 才会落盘. 但是chan有几个缺点, 首先是内存数据,…

Read More

如何做一个靠谱的发号器

为什么需要一个发号器 在使用数据库时,表的主键经常会使用数据库的自增(auto_increment)来产生。这当然很方便也很高效。但是使用自增也会带来一些麻烦。如果从一个数据库以外的地方,也就是发号器来产生全局唯一 ID,这些问题就可以得到解决,生活就可以更美好。 难以适应分片场景 在采用数据库分片时,如果使用数据库自增 ID,不同分片上会产生相同的 ID。单靠 ID 无法唯一标示一个对象,还需要额外加上分片字段才行。如果需要将 ID…

Read More

Redis集群实现原理探讨

Redis集群是一个distribute、fault-tolerant的Redis实现,主要设计目标是达到线性可扩展性、可用性、数据一致性。 线性拓展 官方推荐最大的节点数量为1000,由于Cluster架构中无Proxy层,Master与Slave之间使用异步replication。 数据一致性 客户端容忍一定程度的数据丢失,集群尽可能保存Client write操作的数据,保证数据一致性。 可用性 Redis集群通过partition来提供一定程度的可用性,当集群中的一部分节点失效或者无法进行通讯时,集群仍可以继续提供服务。这里有两点补充: 只要集群中大多数Master可达、且失效的Master至少有一个Slave可达,即集群非Fail状态,…

Read More

TCP网络编程杂谈

作为一名IT工程师,网络通信编程相信都会接触到,比如Web开发的HTTP库,Java中的Netty,或者C/C++中的Libevent,Libev等第三方通信库,甚至是直接使用Socket API,但是很多程序员都仅限于使用,对于使用的方式是否合理并没有特别深的理解,比如有一股脑的使用线程池解决问题的(虽然大部分情况采用多线程方案不会有什么问题,但是编程复杂度比起单线程提升了很多,线程开的太多也会导致切换过于频繁,性能未必有太大提升),也有始终用一条线程处理所有业务的,然后上线之后经常出现各种服务响应慢等问题。 在介绍TCP的网络通信编程时,不得不提到同步,异步,阻塞,非阻塞这几个概念,C+…

Read More