最近在做一个基于Azure云的物联网分析项目:



.netcore采集程序向Azure事件中心(EventHubs)发送数据,通过Azure EventHubs Capture转储到Azure BlogStorage,供数据科学团队分析。

为什么使用Azure事件中心?

Azure事件中心是一种Azure上完全托管的实时数据摄取服务, 每秒可流式传输来自website、app、device任何源的数百万个事件。提供的统一流式处理平台和时间保留缓冲区,将事件生成者和事件使用者分开。

  • 事件生成者: 可使用https、AQMP协议发布事件
  • 分区:事件中心通过分区使用者模式提供消息流式处理功能,提高可用性和并行化
  • 事件接收者:所有事件中心使用者通过AMQP 1.0会话进行连接,读取数据

例如,如果事件中心具有四个分区,并且其中一个分区要在负载均衡操作中从一台服务器移动到另一台服务器,则仍可以通过其他三个分区进行发送和接收。 此外,具有更多分区可以让更多并发读取器处理数据,从而提高聚合吞吐量。 了解分布式系统中分区和排序的意义是解决方案设计的重要方面。 为了帮助说明排序与可用性之间的权衡,请参阅 CAP 定理

最直观的方式:请在portal.azure.cn门户站点---->创建事件中心命名空间---> 创建事件中心

.NetCore 准实时批量发送数据到事件中心

.NET库 (Azure.Messaging.EventHubs)

我们使用Asp.NetCore以Azure App Service形式部署,依赖Azure App Service的自动缩放能录应对物联网的潮汐大流量。

通常推荐批量发送到事件中心,能有效增加web服务的吞吐量和响应能力。

目前新版SDk: Azure.Messaging.EventHubs仅支持分批发送。

  1. nuget上引入Azure.Messaging.EventHubs库
  2. EventHubProducerClient客户端负责分批发送数据到事件中心,根据发送时指定的选项,事件数据可能会自动路由到可用分区或发送到特定请求的分区。

在以下情况下,建议允许自动路由分区:

1) 事件的发送必须高度可用

2) 事件数据应在所有可用分区之间平均分配。

自动路由分区的规则:

1)使用循环法将事件平均分配到所有可用分区中

2)如果某个分区不可用,事件中心将自动检测到该分区并将消息转发到另一个可用分区。

我们要注意,根据选定的 命令空间定价层, 每批次发给事件中心的最大消息大小也不一样:

分段批量发送策略

这里我们就需要思考: web程序收集数据是以个数为单位; 但是我们分批发送时要根据分批的字节大小来切分。

我的方案是: 因引入TPL Dataflow 管道:

  1. web程序收到数据,立刻丢入TransformBlock<string, EventData>
  2. 转换到EventData之后,使用BatchBlock<EventData>按照个数打包
  3. 利用ActionBlock<EventData[]>在包内 累积指定字节大小批量发送
  • 最后我们设置一个定时器(5min),强制在BatchBlock的前置队列未满时打包,并发送。

核心的TPL Dataflow代码如下:

public class MsgBatchSender
{
private readonly EventHubProducerClient Client;
private readonly TransformBlock<string, EventData> _transformBlock;
private readonly BatchBlock<EventData> _packer;
private readonly ActionBlock<EventData[]> _batchSender; private readonly DataflowOption _dataflowOption;
private readonly Timer _trigger;
private readonly ILogger _logger; public MsgBatchSender(EventHubProducerClient client, IOptions<DataflowOption> option,ILoggerFactory loggerFactory)
{
Client = client;
_dataflowOption = option.Value;
var dfLinkoption = new DataflowLinkOptions { PropagateCompletion = true }; _transformBlock = new TransformBlock<string, EventData>(
text => new EventData(Encoding.UTF8.GetBytes(text)),
new ExecutionDataflowBlockOptions
{
MaxDegreeOfParallelism = _dataflowOption.MaxDegreeOfParallelism
});
_packer = new BatchBlock<EventData>(_dataflowOption.BatchSize);
_batchSender = new ActionBlock<EventData[]>(msgs=> BatchSendAsync(msgs));
_packer.LinkTo(_batchSender, dfLinkoption); _transformBlock.LinkTo(_packer, dfLinkoption, x => x != null); _trigger = new Timer(_ => _packer.TriggerBatch(), null, TimeSpan.Zero, TimeSpan.FromSeconds(_dataflowOption.TriggerInterval)); _logger = loggerFactory.CreateLogger<DataTrackerMiddleware>();
} private async Task BatchSendAsync(EventData[] msgs)
{
try
{
if (msgs != null)
{
var i = 0;
while (i < msgs.Length)
{
var batch = await Client.CreateBatchAsync();
while (i < msgs.Length)
{
if (batch.TryAdd(msgs[i++]) == false)
{
break;
}
}
if(batch!= null && batch.Count>0)
{
await Client.SendAsync(batch);
batch.Dispose();
}
}
}
}
catch (Exception ex)
{
// ignore and log any exception
_logger.LogError(ex, "SendEventsAsync: {error}", ex.Message);
} } public async Task<bool> PostMsgsync(string txt)
{
return await _transformBlock.SendAsync(txt);
} public async Task CompleteAsync()
{
_transformBlock.Complete();
await _transformBlock.Completion;
await _batchSender.Completion;
await _batchSender.Completion;
}
}

总结

  • Azure事件中心的基础用法
  • .NET Core准实时分批向Azure事件中心发送数据,其中用到的TPL Dataflow是以actor模型:提供了粗粒度的数据流和流水线任务,提高了高并发程序的健壮性。

如何利用.NETCore向Azure EventHubs准实时批量发送数据?的更多相关文章

  1. html 实时监控发送数据

    我们都知道ajax可以做异步提交,可以从一个文件里得到返回的数据,如此便能够实时的得到数据,实时刷新页面,如下代码 setInterval(function(){ $.ajax({ url:'demo ...

  2. 利用状态机(FSM)进行简单的uart串口发送数据

    module uart_tx(clk,rst_n,key,txd); input clk; input rst_n; input key; output reg txd; :] state; :] b ...

  3. 利用AXI-DMA批量发送数据到DMA

    1.1 主函数 int main(void) { XGpio_Initialize(&Gpio, AXI_GPIO_DEV_ID); XGpio_SetDataDirection(&G ...

  4. Lyft 基于 Flink 的大规模准实时数据分析平台(附FFA大会视频)

    摘要:如何基于 Flink 搭建大规模准实时数据分析平台?在 Flink Forward Asia 2019 上,来自 Lyft 公司实时数据平台的徐赢博士和计算数据平台的高立博士分享了 Lyft 基 ...

  5. 利用Flume将MySQL表数据准实时抽取到HDFS

    转自:http://blog.csdn.net/wzy0623/article/details/73650053 一.为什么要用到Flume 在以前搭建HAWQ数据仓库实验环境时,我使用Sqoop抽取 ...

  6. 基于 Hudi 和 Kylin 构建准实时高性能数据仓库

    在近期的 Apache Kylin × Apache Hudi Meetup直播上,Apache Kylin PMC Chair 史少锋和 Kyligence 解决方案工程师刘永恒就 Hudi + K ...

  7. 基于OGG的Oracle与Hadoop集群准实时同步介绍

    版权声明:本文由王亮原创文章,转载请注明出处: 文章原文链接:https://www.qcloud.com/community/article/220 来源:腾云阁 https://www.qclou ...

  8. 原 荐 使用Spring Boot Actuator、Jolokia和Grafana实现准实时监控

    原 荐 使用Spring Boot Actuator.Jolokia和[可视化]Grafana实现准实时监控.   监控系统:          日志- 基础处理 - 表格 - 可视化一体化解决方案. ...

  9. 大数据学习——点击流日志每天都10T,在业务应用服务器上,需要准实时上传至(Hadoop HDFS)上

    点击流日志每天都10T,在业务应用服务器上,需要准实时上传至(Hadoop HDFS)上 1需求说明 点击流日志每天都10T,在业务应用服务器上,需要准实时上传至(Hadoop HDFS)上 2需求分 ...

随机推荐

  1. Java实现 LeetCode 134 加油站

    134. 加油站 在一条环路上有 N 个加油站,其中第 i 个加油站有汽油 gas[i] 升. 你有一辆油箱容量无限的的汽车,从第 i 个加油站开往第 i+1 个加油站需要消耗汽油 cost[i] 升 ...

  2. java实现第四届蓝桥杯连续奇数和

    连续奇数和 题目描述 小明看到一本书上写着:任何数字的立方都可以表示为连续奇数的和. 比如: 2^3 = 8 = 3 + 5 3^3 = 27 = 7 + 9 + 11 4^3 = 64 = 1 + ...

  3. 震惊!当Python遇到Excel后,将开启你的认知虫洞

    本文主要内容:   1. Excel,你为什么如此强大 2. 软件开发也需要团队作战 3. Excel的集成方案演化 4. macOS特有的集成方案:applescript 5. Python与Exc ...

  4. Python 字符串、列表和元组用法详解

    1.通用函数 len() #列表的元素个数.字符串的长度 2.''' '''与'\ '用法详解 s='''this is a text ''' -->输出s ---> 'this\nis\ ...

  5. linux 删除文件后 df 查看磁盘空间并没有释放

    1.错误现象 Linux 磁盘空间总是报警,查到到大文件,删除之后,df看到磁盘空间并没有释放. 用du -sh ./* | sort -nr (查看当前目录下文件的大小)通过查找了下发现文件被mys ...

  6. 一次性搞懂 PHP 中面向对象的所有知识点。

    OOP是什么? OOP是面向对象编程,面向对象编程是一种计算机编程架构. OOP的基本原则是计算机程序是由单个能起到子程序作用的单元或对象组合而成. 基本概念: 类:定义了事务的抽象特点.包含了数据的 ...

  7. 09.Django-数据库优化

    Django查询数据库性能优化 现在有一张记录用户信息的UserInfo数据表,表中记录了10个用户的姓名,呢称,年龄,工作等信息. models文件 from django.db import mo ...

  8. Controller是什么?

    控制器Controller 控制器复杂提供访问应用程序的行为,通常通过接口定义或注解定义两种方法实现. 控制器负责解析用户的请求并将其转换为一个模型. 在Spring MVC中一个控制器类可以包含多个 ...

  9. DOCLever环境搭建

    简介 DOClever是一个可视化免费开源的接口管理工具 ,可以分析接口结构,校验接口正确性, 围绕接口定义文档,通过一系列自动化工具提升我们的协作效率. 环境搭建 准备: node: 官方下载:ht ...

  10. Nginx配置rewrite过程介绍

    创建rewrite语句 vi conf/vhost/www.abc.com.conf #vi编辑虚拟主机配置文件 文件内容 server { listen 80; server_name abc.co ...