1. Aeron入门简述

765 阅读3分钟

背景

由于作者所在公司是做在线交易的,业务特性决定我们在做系统设计的时候,对系统处理耗时,要做到很低,这样才能尽快的触发成交,提高用户体验。当前服务架构是把用户按照用户id % 512进行取模,平均分布到N台机器上,每台机器只负责确定的521/N的分片数据,这样做的好处在于,同一个用户的请求会固定的打到某一台机器上。在机器内部,同一个用户的所有请求,会按照顺序在一个队列内排队执行(这个队列就是disruptor), 用户相关的所有数据,都缓存在内存里,内存化+无锁,实际用户请求的耗时就很低。这样做缺点在于,服务是有状态的,所以平时对于数据的处理,要保证服务重启前后,程序的状态是一致,同时,每次服务发布期间,系统其实是不可用的。因此为了提升用户体验,决定对有状态的服务进行高可用

高可用

平时大家可能更多关注对于无状态服务的高可用,比如分批滚动发布、数据库主从、更复杂的有异地多活等等,近今年随着互联网企业的兴起,各种高可用方案层出不穷这里就不多赘述了,但是有状态服务的高可用怎么实现呢?不知道大家有没有关注过这个问题

什么是Aeron?

Aeron这个架构我估计大家很多人都没听过,包括我在内。公司内部核心的交易系统在过去的两年里,已经逐渐的迁移到这个架构上了,我们也算是前人栽树,后人乘凉。直接向人家请教就可以。这里我想用一句话总结aeron框架的作用:基于raft协议,可以快速构建低延迟,高可用的网络架构;可能不是那么精确,但是也应该清晰的描述了这个架构的作用。aeron的demo实际上看起来很简单,但是要想弄其核心流程,还是有一些难度,目前网络上对这个框架中文资料很少,几乎没有,所以学习的过程只能通过阅读官方文档+debug源码的方式,自己也算是看了三四个月,也有了一些收获,后面会逐渐的开展这个系列的核心源码解读,废话不多说了,直接上架构图

image.png 核心点:sub,media driver,pub

demo

public static void main(String[] args)
{
    final String channel = "aeron:ipc";
    final String message = "my message";
    final IdleStrategy idle = new SleepingIdleStrategy();
    final UnsafeBuffer unsafeBuffer = new UnsafeBuffer(ByteBuffer.allocate(256));
    try (MediaDriver driver = MediaDriver.launch();
        Aeron aeron = Aeron.connect();
        Subscription sub = aeron.addSubscription(channel, 10);
        Publication pub = aeron.addPublication(channel, 10))
    {
        while (!pub.isConnected())
        {
            idle.idle(); // 简单理解为阻塞即可
        }
        unsafeBuffer.putStringAscii(0, message);
        System.out.println("sending:" + message);
        while (pub.offer(unsafeBuffer) < 0)
        {
            idle.idle();
        }
        FragmentHandler handler = (buffer, offset, length, header) ->
            System.out.println("received:" + buffer.getStringAscii(offset));
        while (sub.poll(handler, 1) <= 0)
        {
            idle.idle();
        }
    }
}

result:

sending:my message
received:my message

学废了吗?

上述架构图和demo,看起来好像很简单,一个发布者,一个订阅者,以及一个不知道干什么的“media driver”。发布者可以在channel上进行数据发布,订阅者可以在通过订阅这个channel来接受数据,数据会通过media driver来传输,发布者和订阅者可以在同一台机器上,也可以分布在不同机器上。但是我怎么借助上面的发布/订阅模式实现高可用架构呢?别着急,上面的发布和订阅,实际上是aeron集群内用来做数据传输的交互方式,比如主从之间的数据传输、以及未来还会提到的replay,本质上都是通过发布订阅的模式来进行数据的同步,我们前期的源码分析,都会从上面的例子入手,逐渐的一层一层的揭开aeron的面纱。

参考资料