• [知识分享] 优化分布式文件系统中的文件同步速度
    在使用分布式文件系统时,我发现某些文件在多个节点之间的同步速度非常慢,尤其是在网络条件不佳的情况下。具体表现为,当一个节点上传了一个大文件后,其他节点需要很长时间才能完成同步,有时甚至会出现同步失败的情况。这不仅影响了系统的整体性能,还导致了数据的一致性问题。请问,有哪些方法可以优化分布式文件系统中的文件同步速度,特别是在网络条件不佳的情况下。在优化分布式文件系统中的文件同步速度时,可以采用多种策略来提高效率和可靠性。首先,通过分块传输将大文件分割成多个小块,每个节点可以并行处理不同的块,这样不仅减少了单个传输任务的等待时间,还提高了整体的并行度。如果某个块传输失败,只需要重传该块,而不是整个文件,从而减少了重传的时间和带宽消耗。其次,差量同步技术可以在每次同步时只传输文件的增量部分,而不是整个文件,这在文件内容变化不大时特别有效,可以显著减少传输的数据量,特别是在网络条件不佳的情况下,能够显著提高同步速度。此外,使用可靠传输协议如Quic或SCTP,这些协议在高丢包率和不稳定网络环境中表现更好,能够更有效地处理数据重传,减少同步失败的可能性。节点间的负载均衡也是关键,通过合理分配任务,避免某些节点过载,确保每个节点都能高效地处理同步任务,提高整体系统的性能。最后,优化网络带宽管理,例如使用数据压缩和加密技术,可以减少传输的数据量,提高传输速度。同时,设置带宽优先级,确保关键数据优先传输,减少延迟,从而在整体上提升分布式文件系统的同步速度和数据一致性。
  • [大赛资讯] n_abort_error
    提交后反馈信息是“n_abort_error”,请问能知道具体是什么错误吗?
  • [课程学习] 开年第一课——HarmonyOS精品课程推荐
    又是一年开学、开工季人已在学校上课和工位上班脑子却在迷茫不知道做什么别再摸鱼啦!新的一年学习目标来啦!专为零基础小白提供的5门行业大会的HarmonyOS精品课程。这些课程由权威技术大咖讲解,深入浅出带你轻松理解鸿蒙应用基础概念,助力你全面掌握前沿技术,拥抱职业发展的无限可能!1.精品课程《鸿蒙:万物智联时代的操作系统》,请戳学习链接2.精品课程《鸿蒙应用开发:从Android到HarmonyOS》,请戳学习链接3.精品课程《鸿蒙分布式软总线的前世今生》,请戳学习链接4.精品课程《万物智联下的HarmonyOS开发框架》,请戳学习链接5.精品课程《Zelda :鸿蒙应用静态分析框架》,请戳学习链接
  • [问题求助] 如何优化分布式系统的性能和响应速度?
    如何优化分布式系统的性能和响应速度?
  • [其他] 微服务RPC框架:Feign和Dubbo
    一、Feign是什么? Feign是Spring Cloud提供的一个声明式的伪Http客户端,它使得调用远程服务就像调用本地服务一样简单,只需要创建一个接口并添加一个注解即可。 Nacos注册中心很好的兼容了Feign,Feign默认集成了Ribbon,所以在Nacos下使用Fegin默认就实现了负载均衡的效果。  二、Dubbo是什么? Dubbo是阿里巴巴开源的基于Java的高性能RPC分布式服务框架,致力于提供高性能和透明化的RPC远程服务调用方案,以及SOA服务治理方案。 Spring-cloud-alibaba-dubbo是基于SpringCloudAlibaba技术栈对dubbo技术的一种封装,目的在于实现基于RPC的服务调用。  三、对比 Feign和Dubbo都可以实现远程调用,他们都依赖注册中心,他们都支持负载均衡,服务熔断。  然而Feign是基于Http协议。服务提供者需要对外暴露Http接口供消费者调用(例如我们用@openFeign注解来标识远程调用服务的接口时,需要加@RequestMapping)服务粒度是http接口级的。通过短连接的方式进行通信,不适合高并发的访问。Feign追求的是简洁,少侵入(因为就服务端而言,在SpringCloud环境下,不需要做任何额外的操作,而Dubbo的服务端需要配置开放的Dubbo接口)。  至于Dubbo,Dubbo支持多传输协议(Dubbo、Rmi、http、redis等等),可以根据业务场景选择最佳的方式,非常灵活。默认的Dubbo协议:利用Netty,TCP传输,单一、异步、长连接,适合数据量小、高并发和服务提供者远远少于消费者的场景。Dubbo通过TCP长连接的方式进行通信,服务粒度是方法级的。  从协议层选择看,Dubbo是配置化的,更加灵活。Dubbo协议更适合小数据高并发场景。  欸,不要急,肯定有人看到这里会有问题,长连接和短连接区别是什么,为什么基于短连接的Feign就不适合高并发的访问呢,为什么长连接的Dubbo就可以。  四、长连接和短连接 说到长连接和短连接,很多人都会想到Http长连接和短连接的相关知识,例如Http1.0默认使用短连接,Http1.1默认使用长连接呀之类的,但经过笔者学习和阅读一些文章之后,实际上Http根本不分长连接和短连接,或者说“ Http的长短连接,其实是在Tcp连接中实现的 ”。  HTTP协议的长连接和短连接,本质上是TCP协议的长连接和短连接。HTTP属于应用层协议,在传输层使用TCP协议,在网络层使用IP协议。 IP协议主要解决网络路由和寻址问题,TCP协议主要解决如何在IP层之上可靠地传递数据包,使得网络上接收端收到发送端所发出的所有包,并且接受顺序与发送顺序一致。TCP协议是可靠的、面向连接的。TCP才负责连接,只有负责传输的这一层才需要建立连接!!!!!  在HTTP/1.0中默认使用短连接。也就是说,客户端和服务器每进行一次HTTP操作,就建立一次连接,任务结束就中断连接。当客户端浏览器访问的某个HTML或其他类型的Web页中包含有其他的Web资源(如JavaScript文件、图像文件、CSS文件等),每遇到这样一个Web资源,浏览器就会重新建立一个HTTP会话。  而从HTTP/1.1起,默认使用长连接,用以保持连接特性。使用长连接的HTTP协议,会在响应头加入这行代码(但要服务器和客户端都设置):Connection:keep-alive   那么综合长短连接来说呢,Feign是短连接的,那我们面对高并发的请求的时候,每请求一次数据都要建立一次连接,那肯定就不适用了。所以,Feign和Dubbo都能实现远程调用的功能,但是要看我们具体的需求去使用哪个。  补充一点: 在使用长连接的情况下,当一个网页打开完成后,客户端和服务器之间用于传输HTTP数据的TCP连接不会关闭,客户端再次访问这个服务器时,会继续使用这一条已经建立的TCP连接。也就是说在长连接情况下,多个HTTP请求可以复用同一个TCP连接,这就节省了很多TCP连接建立和断开的消耗。  Keep-Alive不会永久保持连接,它有一个保持时间,可以在不同的服务器软件(如Apache)中设定这个时间。实现长连接需要客户端和服务端都支持长连接。  五、长轮询,短轮询 既然前面已经提到了长连接和短连接,那么其实我们在实际应用开发的过程中,还会碰到长轮询和短轮询的选择,所以在这里也一并进行学习和记录啦。  首先我们想象一个业务场景,现在有一个商品正在销售(正常网购场景,并非秒杀)。商品的旁边要显示它的库存量,并且这个库存量是要时实变化的,那我们该怎么处理。  首先短轮询的方法,我们可以去编写一个JS函数,每一秒就去查询一次数据,然后把得到的结果在界面中渲染,进行刷新。我们使用短轮询的方法,所以每次去请求一次数据,都会建立一个连接,请求完毕再关闭连接,再请求,再建立,再关闭。   这种短轮询肯定是会造成网络资源的浪费的,因为如果有几万个用户,他就是在浏览界面,然后忘了关闭,也不下单,那就同时有几个万个请求在创建连接,关闭连接。。。   长轮询这个时候就出现了,其实长轮询和短轮询最大的区别是,短轮询去服务端查询的时候,不管库存量有没有变化,服务器就立即返回结果了。而长轮询则不是,在长轮询中,服务器如果检测到库存量没有变化的话,将会把当前请求挂起一段时间(这个时间也叫作超时时间,一般是几十秒)。在这个时间里,服务器会去检测库存量有没有变化,检测到变化就立即返回,否则就一直等到超时为止。  而对于客户端来说,不管是长轮询还是短轮询,客户端的动作都是一样的,就是不停的去请求,不同的是服务端,短轮询情况下服务端每次请求不管有没有变化都会立即返回结果,而长轮询情况下,如果有变化才会立即返回结果,而没有变化的话,则不会再立即给客户端返回结果,直到超时为止。  这样一来,客户端的请求次数将会大量减少(这也就意味着节省了网络流量,毕竟每次发请求,都会占用客户端的上传流量和服务端的下载流量),而且也解决了服务端一直疲于接受请求的窘境。  但是长轮询也是有坏处的,因为把请求挂起同样会导致资源的浪费,假设还是1000个人停留在某个商品详情页面,那就很有可能服务器这边挂着1000个线程,在不停检测库存量,这依然是有问题的。  因此,从这里可以看出,不管是长轮询还是短轮询,都不太适用于客户端数量太多的情况,因为每个服务器所能承载的TCP连接数是有上限的,这种轮询很容易把连接数顶满。哪怕轮询解决不了获取库存这个问题,但只要大家明白了长短轮询的区别,这就足够了。  六、Feign和Dubbo其他方面的区别 好了,言归正传,最后再介绍一些Feign和Dubbo在其他方面的区别。 负载均衡方面: Feign默认使用Ribbon作为负载均衡的组件。 Dubbo和Ribbon(Feign默认集成Ribbon)都支持负载均衡策略,但是Dubbo支持的更灵活。 Dubbo和Ribbon对比: Ribbon的负载均衡策略:随机、规则轮询、空闲策略、响应时间策略。 Dubbo的负载均衡策略:Dubbo支持4种算法,随机、权重轮询、最少活跃调用数、一致性Hash策略。而且算法里面引入权重的概念。 Dubbo可以使用路由策略,然后再进行负载均衡。 Dubbo配置的形式不仅支持代码配置,还支持Dubbo控制台灵活动态配置。 Dubbo负载均衡的算法可以精准到某个服务接口的某个方法,而Ribbon的算法是Client级别的。Ribbon需要进行全局配置,个性化配置比较麻烦。  容错机制方面: Feign默认使用Hystix作为服务熔断的组件。Hystix提供了服务降级,服务熔断,依赖隔离,监控(Hystrix Dashboard)等功能。Feign是利用熔断机制来实现容错的,与Dubbo处理的方式不一样。  Dubbo支持多种容错策略,FailOver、FailFast、Failsafe、FailBack、Aviailable、Broadcast、Forking策略等,以及Mock。也引入了retry次数,timeout等配置参数。Dubbo自带了失败重试的功能。 总结 Dubbo支持更多功能、更灵活、支持高并发的RPC框架。 SpringCloud全家桶里面(Feign、Ribbon、Hystrix),特点是非常方便。Ribbon、Hystrix、Feign在服务治理中,配合Spring Cloud做微服务,使用上有很多优势,社区也比较活跃,看将来更新发展。 业务发展影响着架构的选型,当服务数量不是很大时,使用普通的分布式RPC架构即可,当服务数量增长到一定数据,需要进行服务治理时,就需要考虑使用流式计算架构。Dubbo可以方便的做更精细化的流量调度,服务结构治理的方案成熟,适合生产上使用,虽然Dubbo是尘封后重新开启,但这并不影响其技术价值。 如果项目对性能要求不是很严格,可以选择使用Feign,它使用起来更方便。 如果需要提高性能,避开基于Http方式的性能瓶颈,可以使用Dubbo。 Dubbo Spring Cloud的出现,使得Dubbo既能够完全整合到Spring Cloud的技术栈中,享受Spring Cloud生态中的技术支持和标准化输出,又能够弥补Spring Cloud中服务治理这方面的短板。  原文链接:https://blog.csdn.net/weixin_56032340/article/details/123619132 
  • [其他] 分布式锁的实现方式
    Java中的锁主要包括synchronized锁和JUC包中的锁,这些锁都是针对单个JVM实例上的锁,对于分布式环境如果我们需要加锁就显得无能为力。在单个JVM实例上,锁的竞争者通常是一些不同的线程,而在分布式环境中,锁的竞争者通常是一些不同的线程或者进程。目前主要有三种方式实现分布式系统中的锁方式:分布式锁的实现方式基于数据库唯一索引基于缓存Redis基于Zookeeper1.基于数据库唯一索引方式主要利用数据库唯一索引的排他性实现,同一个业务id如果能插入数据成功就认为是获得了锁,插入失败就是锁被占用,释放锁就是删除数据。虽然实现方式简单但是因为数据库的可承载并发量有限所以性能方面并不好,并且可能会造成死锁等问题。2.基于缓存Redis的方式理论上来说借助于Redis实现的分布式锁效率最好,主要借助于Redis的Setnx命令同一个业务id如果已经存在就返回0,不存在就返回1并设置成功。因为Redis是纯内存操作所以效率最高,结合Redis的失效时间等方式可以很大程度的避免死锁问题。借助于Redisson工具可以很好的实现分布式锁方式。3.基于Zookeeper方式Zookeeper一般作为配置中心和注册中心,借助于Zookeeper创建临时节点的排他性并且在断开连接时自动销毁临时节点的特性可以实现分布式锁。加锁就是创建节点,释放锁就是断开连接,但因为牵涉到Zookeeper牵涉到文件存储所以效率没有Redis高。Zookeeper第三方客户端curator中已经实现了基于Zookeeper的分布式锁。
  • [其他] 分布式事务框架
    分布式事务 在微服务项目开发过成功各个模块之间是隔离的,如果在链式调用过程中由于某个模块没有执行成功会造成数据不一致的问题,因此我们需要在链式调用过程中使用分布式事务组件实现统一的提交和异常回滚保证数据的一致性。  Spring cloud alibaba 分布式事务组件 Seata Seata 是一款开源的分布式事务解决方案,致力于提供高性能和简单易用的分布式事务服务。Seata 将为用户提供了 AT、TCC、SAGA 和 XA 事务模式,为用户打造一站式的分布式解决方案。。 使用@GlobalTransactional注解来实现一个分布式事务。具体的业务就是,我们自己有一个事务管理,当我们的业务在保存的时候出现问题,我们单据就会回滚,不会保存,然后我们会调用流程平台的代码(也就是Activiti),然后问题出现了,在调用的时候出现了问题,流程没有取到数据,我们因为因为出错所以就回滚了,但是Activiti捕捉了这个异常,并且成功发起的流程,这就导致了单据显示在用户的我发起的和代办中,我们就换一个注解实现全局事务GlobalTransactional。  官网文档:cid:link_0 Spring cloud 项目集成 Seata组件 1.下载Seata服务 从 https://github.com/seata/seata/releases,下载服务器软件包,将其解压缩  2.修改配置 打开conf/file.conf文件 修改service 节点目录内容如下: service {   #vgroup->rgroup   vgroup_mapping.my_test_tx_group = "default"   #only support single node   default.grouplist = "127.0.0.1:8091"   #degrade current not support   enableDegrade = false   #disable   disable = false   #unit ms,s,m,h,d represents milliseconds, seconds, minutes, hours, days, default permanent   max.commit.retry.timeout = "-1"   max.rollback.retry.timeout = "-1" }  3.启动Seata服务 到bin目录下执行脚本启动seata server端,注:windows下执行seata-server.bat启动;linux下执行seata-server.sh启动  ### 4.引入依赖 ``` <dependency>     <groupId>io.seata</groupId>     <artifactId>seata-spring-boot-starter</artifactId>     <version>最新版</version> </dependency> <!--不使用注册中心、配置中心不加--> <dependency>     <groupId>com.alibaba.nacos</groupId>     <artifactId>nacos-client</artifactId>     <version>1.2.0及以上版本</version> </dependency>  ```  ### 5.application.yml配置 ``` seata:     enabled: true     enable-auto-data-source-proxy: false     application-id: ${spring.application.name}     tx-service-group: my_tx_group       service:         vgroup-mapping:             my_tx_group: default  # 不使用注册中心和配置中心不加以下配置     config:         type: nacos         nacos:             server-addr: 127.0.0.1:8848             group: "SEATA_GROUP"             namespace: "seata"             dataId: "seataServer.properties"             username: ""             password: ""     registry:         type: nacos         nacos:             application: seata-server             server-addr: 127.0.0.1:8848             group: "SEATA_GROUP"             namespace: "seata"             username: ""             password: ""  ```  ### 6.数据库中添加回滚日志表 数据源连接的每个数据库中添加 undo_log 表 ``` CREATE TABLE `sys_seata_undo_log` (   `id` bigint(20) NOT NULL AUTO_INCREMENT,   `branch_id` bigint(20) NOT NULL,   `xid` varchar(100) NOT NULL,   `context` varchar(128) NOT NULL,   `rollback_info` longblob NOT NULL,   `log_status` int(11) NOT NULL,   `log_created` datetime NOT NULL,   `log_modified` datetime NOT NULL,   PRIMARY KEY (`id`),   UNIQUE KEY `ux_undo_log` (`xid`,`branch_id`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;  ```  ### 7.客户端application.yml配置 ``` seata:   tx-service-group: default_tx_group   service:     vgroup-mapping:       default_tx_group: default  ```  ### 8.在分布式事务控制方法上添加注解@GlobalTransactional ```    @GlobalTransactional     public void purchase(String userId, String commodityCode, int orderCount) {         ......     } ``` 
  • [设备专区] 如何配置VLAN?
    边缘计算模式如何配置VLAN呢
  • [知识分享] 分布式协同AI基准测试项目Ianvs:工业场景提升5倍研发效率
    摘要:全场景可扩展的分布式协同AI基准测试项目 Ianvs(雅努斯),能为算法及服务开发者提供全面开发套件支持,以研发、衡量和优化分布式协同AI系统。 本文分享自华为云社区《KubeEdge|分布式协同AI基准测试项目Ianvs:工业场景提升5倍研发效率》,作者 华为云|郑子木。 在边缘计算的浪潮中,AI是边缘云乃至分布式云中最重要的应用。随着边缘设备的广泛使用和性能提升,将人工智能相关的部分任务部署到边缘设备已经成为必然趋势。KubeEdge-Sedna子项目,作为业界首个分布式协同AI框架,基于KubeEdge提供的边云协同能力,支持现有AI类应用无缝下沉到边缘,降低分布式协同机器学习服务构建与部署成本、提升模型性能、保护数据隐私等。本篇文章为大家阐释分布式协同AI技术背景,研发落地三大生态挑战和社区调研报告,并对全新社区SIG AI子项目(于KubeEdge Summit 2022 重磅发布):全场景可扩展的分布式协同AI基准测试项目 Ianvs(雅努斯),进行介绍。该项目能为算法及服务开发者提供全面开发套件支持,以研发、衡量和优化分布式协同AI系统。欢迎关注Ianvs项目,持续获得第一手独家公开数据集与完善基准测试配套。开源项目GitHub地址:cid:link_101 分布式协同AI技术背景随着边侧算力逐步强化,时代也正在见证边缘AI往分布式协同AI的持续演变。分布式协同AI技术是指基于边缘设备、边缘服务器、云服务器利用多节点分布式乃至多节点协同方式实现人工智能系统的技术。虽然还在发展初期,分布式协同AI成为必然趋势的驱动力主要有二。第一,由于数据首先在边缘产生,有大量数据处理需要在边侧运行。第二,由于边侧逐步具备AI能力,高阶数据处理需要在边侧运行。在实际应用场景中,以往常见的是云上训练、边侧推理模式,现在在各个场合已经频繁听到边云协同推理、边云协同增量学习、边云协同终身学习、联邦学习等协同模式,可以看到边缘AI向边云协同乃至分布式协同的演进正在发生。上述这些都使得我们有理由相信,分布式协同AI是大势所趋。关于分布式协同AI的产业发展形态,根据Research Dive Analysis预测,全球边缘AI乃至分布式协同AI软件(算法、平台等)市场规模将从2019年的4.36亿美元增长到2023年的30.93亿美元。分布式协同AI解决方案市场规模比例显著大于服务。也就是说,与直接提供通用服务相比,结合行业解决方案可能是分布式协同AI商业变现的主要途径。至于与行业解决方案结合的话,据麦肯锡预测,边缘AI乃至分布式协同AI至少覆盖12个行业。可以看到,相关行业解决方案的市场领域多样化,通过产业链聚拢乃至垄断方式来收割商业价值无疑存在规模复制挑战。因此,从产业发展形态出发考虑,一家企业独大并不可取,与生态伙伴同行才有可能走得更远。鉴于上述分布式协同AI技术趋势和产业发展形态,KubeEdge社区基于CNCF成熟治理模式,成立了KubeEdge SIG AI。其工作目标是基于 KubeEdge 的边云协同能力,提供具有低成本、高性能、易用性、隐私保护等优势的边缘智能平台。SIG AI工作范围包括:1、 构建分布式协同AI框架,高效合理利用端、边、云的各类资源,并能根据负载和应用类型实时地进行模型调度,实现高性能和低成本兼备的边缘AI系统。2、 构建分布式协同AI基准测试,识别AI系统中重要指标,帮助用户评估边缘AI系统的功能和性能,以衡量和优化分布式协同AI系统,揭露各应用场景的最佳实践。    3、积极与周边AI平台、边缘智能硬件厂商等伙伴开展合作,实现自动化的异构资源匹配,减少用户管理异构资源的工作量,提升AI 应用的部署管理维护效率。02 分布式协同AI应用落地挑战调研报告KubeEdge SIG AI及整个行业各个技术方案落地与成果转化到产业的进程正在紧锣密鼓地进行,大家也经常提到sedna进入质检、卫星和园区的案例。但仅凭技术是不足够完成落地和产业转化的。当前学界业界很多团队已经遇到各式各样的困难。社区从算法开发者、服务开发者和技术布道者三种边缘AI研发角色的需求出发,启动了边缘AI研发落地生态挑战问卷调研,希望进一步了解边缘AI方案落地与产业转化过程中遇到的,诸如研发资源难获取、工具链不完备等主要依赖社区分工与共享的生态挑战。截止2021年9月20日已回收有效答卷180份。调研结果发现了20+生态挑战,问卷开放选项采集到49条补充意见和8条补充建议。• 调研对象职业主要是工业界从业者(53.45%),其次是在校学生(31.03%)和学术界研究者(25.86%)。• 调研对象的技术方向主要是边缘AI及其应用(55.75%)、AI及其应用(49.43%)、边缘计算及其应用(42.53%)。也有约四分之一的方向为云计算及其应用(25.86%),以及少量的其它方向(13.22%)。基于调研结果已发布业界首份边缘AI落地生态挑战调研报告,可通过下方二维码扫描获取。我们也绘制了三种不同角色所反馈的生态挑战词云。报告的重点内容简要介绍如下:• 对于算法开发者排名第一的挑战是实际业务数据集及配套算法难以获取,排名第二的挑战是重复部署整套端边云系统过于沉重。从中我们可以对于算法开发总结出研发资源支持少的生态挑战。• 对于服务开发者排名第一的挑战是通用方案整体性能不一定满足特定业务需求,排名第二的挑战是自研业务算法和系统方案周期长成本高。从中我们可以针对服务开发总结出方案选型成本高的生态挑战。• 对于技术布道者排名第一的挑战是缺乏商业成功案例,排名第二的挑战是缺乏与现有方案系统对比,包括成本、部署要求。从各挑战中可以针对技术布道者总结出价值呈现晦涩理解难的生态挑战。基于本次调研,我们从刚刚提到的几个挑战出发,进一步了解这个领域各位开发者的心声和行业痛点,探索可能的解决方案。核心痛点 I:业务数据集及其配套算法难以获取在调研过程,算法开发者跟社区反馈得最多的还是业务数据集机器配套算法难以获取• 正在打造边缘AI算法利器,有什么实际业务可以练兵吗,在哪找?• 我认识一家边缘计算公司在做工业质检,质检靠谱数据有吗?可以先试一试。• 公开数据集太多,大海捞针翻到头都秃了。• 数据集要么质量不太高,或者要么跟具体业务不太匹配……• 真实、好用的数据集说起来轻巧,但新业务数据集找起来太累了吧。• 也不知道找哪家公司合适;自己去买设备采集?从中可总结出核心痛点:业务数据集及其配套算法难以获取,同时封闭测试环境难以跟上各类新业务孵化。同时看到第一个需求:分布式协同AI标准数据集和配套算法管理与下载,快速上手真实业务。核心痛点 II:通用方案不满足特定需求在调研过程,服务开发者跟社区反馈得最多的则是通用方案不一定满足特定业务需求。• 业务问题多得很……一宿一宿睡不着,天天挨客户骂,现场各种安抚疲于奔命。顶会论文?真的没有时间看。• 现有测试数据和指标要求与实际业务差距过大。听说算法进展很快,但调研大半年,尝试很多算法,要真正能做进客户心窝里还是很困难的。• 新业务不断产生,现有测试需要对应改进。但现有测试都是那几个玩具数据集和指标,基准固化后还不能改。亟需针对特定场景个性化配置。• 场景很多,问题更多。针对不同场景甚至相同场景的不同算法范式要针对不同架构、接口和参数使用不同测试工具。这导致在不同边侧场景,进行各种测试实验非常繁琐。要规模化被迫采用简单技术。• 自研人力物力成本高,比如设备贵、人才高薪。挑战复杂难题?中小企业试试就逝世,不如交给大企业或者高校(躺)。从中可总结出核心痛点:全场景多范式测试成本高、个性化场景的测试用例准备繁琐。同时看到第二个需求:个性化、全场景测试乃至自动化测试,对症下药并降低研发成本。03 分布式协同AI基准测试Ianvs项目开源发布针对上述痛点和挑战,KubeEdge SIG AI也为大家带来了一个全新的社区子项目 全场景可扩展的分布式协同AI基准测试工具 Ianvs来解决以上问题。借助单机就可以完成分布式协同AI前期研发工作。项目地址:cid:link_1全场景可扩展的分布式协同AI基准测试工具 Ianvs1、 针对业务数据集难以获取,数据采集与处理成本高的痛点,ianvs提供丰富AI生态,做到开箱即用。ianvs开源数据集与5+配套算法,覆盖预处理、预训练、训练、推理、后处理全流程,零改造开箱即用。2、 针对封闭测试环境难跟上各类新业务孵化的痛点,ianvs提供可扩展开放工具链。测试环境管理实现自定义动态配置测试数据集、指标,告别封闭守旧的测试环境。3、 针对全场景多范式测试成本高的痛点,ianvs提供全场景灵活切换。ianvs测试用例管理统一不同场景及其AI算法架构与接口,能用一套工具同时兼容多种AI范式。4、 针对个性化场景的测试用例准备繁琐的痛点,ianvs提供低代码生成测试用例。ianvs测试用例管理基于网格搜索等辅助生成测试用例,比如一个配置文件即可实现多个超参测试,降低超参搜索时的繁琐重复编程。Ianvs同步发布一个新的工业质检数据集PCB-AoI。PCB-AoI 数据集是开源分布式协同 AI 基准测试项目 KubeEdge-Ianvs 的一部分。 Ianvs 很荣幸成为第一个发布此数据集的站点,Ianvs 项目相关社区成员将PCB-AoI 公共数据集同时也放在 Kaggle和云服务上方便各位下载。PCB-AoI工业质检公开数据集下载链接请参见:https://ianvs.readthedocs.io/en/latest/proposals/scenarios/industrial-defect-detection/pcb-aoi.htmlPCB-AoI数据集由KubeEdge SIG AI 来自中国电信和瑞斯康达的成员发布。在这个数据集中,收集了 230 多个板,图像数量增加到 1200 多个。具体来说,数据集包括两部分,即训练集和测试集。训练集包括 173 个板,而测试集包括 60 个板。也就是说,就 PCB 板而言,train-test 比率约为 3:1。进行了数据增强,将图像方面的训练测试比率提高到 1211:60(约 20:1)。 train_data 和 test_data 的两个目录都包含索引文件,用于关联原始图像和注释标签。这里同步展示一个Ianvs在工业场景的案例。本案例是基于PCB-AoI数据集的工业质检。该案例基于工业视觉AoI设备输出视频图片,检测PCB板是否存在贴装异常。案例提供了单任务学习和边云协同增量学习两种范式。在本案例的单任务学习范式中,数据全部上云,在训练阶段获得所有数据。在本案例的边云协同增量学习范式中,数据部分上云,训练数据分两轮提供。Ianvs除算法指标外,还可监控系统指标,如样本上云比例指标。测试的基础模型选用特征图金字塔网络FPN(Feature Pyramid Networks)。基准测试结果显示,待测FPN算法F1性能在0.84-0.95波动。边云协同增量学习可节省近50%的上云数据量,同时获得10%以上的精度提升。如下图所示,增量前1处漏检:仅检出7处,增量后全部检出:检出全部8处缺陷。Ianvs将提供开箱即用的数据集与配套算法,借助支持多场景范式切换和易扩展的工具链,以及测试用例的低代码自动生成能力,来降低开发者在分布式协同AI应用开发测试时的门槛,技术验证时间半年降低到1个月,提升5倍研发效率。Ianvs发布之际在此也特别感谢社区10+初创单位。社区也持续募集在Ianvs项目上的合作伙伴,共同孵化开源项目、研究报告及行业标准等。KubeEdge-Ianvs 初创单位04 Ianvs未来工作展望对于未来工作上,Ianvs项目希望进一步解决各位社区用户的问题。首先,算法开发者们投票第二位的挑战是重复部署端边云系统费时费力的问题• 只是想聚焦系统上的分布式调度而已,需要自己把迁移学习、增量学习、联邦学习算法啥的协同机器学习算法学一遍很痛苦• 想聚焦系统上的AI算法而已,真需要写那么多系统代码,把整一套边云协同系统自己搭起来非常不友善• 费力气搭系统,也不足以落地应用到工业界……工业界有些系统机制,包括模型管理和维护等,能为模型上线护航• 好了,组里花大钱搭起来,系统和算法终于能用了,但眼看着一年过去,马上毕业来不及科研……AI系统的构建对于高校团队来说费时过长成本过高,简直大坑• 很多公司已经有了,重复造轮子感觉憋屈。想在巨人肩膀上实现系统突破,搞大事情因此第一项未来工作可以是实现工业级分布式协同系统仿真,提升方案研发效率。另外一个未来工作,可以是关于技术布道者和最终用户的价值呈现问题• 缺乏与先前方案的对比。受众不明白什么是边缘,跟以前有什么区别• 客户有数据,伙伴有研发,但因数据使用协议,数据无法出边缘,经常需要驻场调整• 没有界面,缺乏demo,方案不直观,客户看不懂,没有吸引力因此第二项未来工作可以是算法/范式测试排行与最佳方案展示,做好价值呈现。Ianvs项目规划路标如下图。欢迎关注Ianvs项目,持续获得第一手独家公开数据集与完善基准测试配套。社区也持续募集在Ianvs项目上的合作伙伴,共同孵化开源项目、研究报告及行业标准等。开源项目GitHub地址:cid:link_1Ianvs 项目路标
  • [其他] 并发操作列存表报锁超时场景
    # 一、问题描述 生产环境,执行update/delete相关业务操作时,业务报错: ERROR: dn_6003_6004: Lock wait timeout: thread 139858583217920 on node dn_6003_6004 waiting for ShareLock on transaction 55363311 after 120000.061 ms # 二、问题背景 并发操作列存表 # 三、问题分析 分布式环境下,列存表的最小存储单位是CU,如果并发操作同一个CU时,可能会产生等锁报错; # 四、问题解决 对并发操作进行串行: 原业务语句: ``` start transaction; delete from TARGET_A where xxx='xxx’; ........ update TARGET_A where xxx='xxx’…… end transaction; ``` 修改后 在update语句前增加一个select语句,在每一个业务操作前,修改如下: ``` start transaction; select name from CONTROL_TABLE where name = 'target_a' for update; delete from TARGET_A where xxx='xxx’; ........ update TARGET_A where xxx='xxx’…… end transaction; ``` control_table为新建行存表,只有一个字段,字段的取值为要更新的目标表名。 # 五、问题总结 并发update/delete在分布式环境比较常见,如果业务不想产生等锁报错可以串行执行。 在并发更新同一张目标表时,首先会利用这张表获取对应记录的行级锁,其他并发任务等待行级锁释放;等到前序事务提交完成后,释放control_table的行级锁,后续事务获取行存表的行锁后,再提交update列存表语句。通过这种方式实现delete/update语句的串行执行,避免并发更新的锁超时报错。
  • [其他] 并发操作列存表报锁超时场景
    # 一、问题描述 生产环境,执行update/delete相关业务操作时,业务报错: ERROR: dn_6003_6004: Lock wait timeout: thread 139858583217920 on node dn_6003_6004 waiting for ShareLock on transaction 55363311 after 120000.061 ms # 二、问题背景 并发操作列存表 # 三、问题分析 分布式环境下,列存表的最小存储单位是CU,如果并发操作同一个CU时,会产生分布式锁; # 四、问题解决 对并发操作进行串行: 原业务语句: ``` start transaction; delete from TARGET_A where xxx='xxx’; ........ update TARGET_A where xxx='xxx’…… end transaction; ``` 修改后 在update语句前增加一个select语句,在每一个业务操作前,修改如下: ``` start transaction; select name from CONTROL_TABLE where name = 'target_a' for update; delete from TARGET_A where xxx='xxx’; ........ update TARGET_A where xxx='xxx’…… end transaction; ``` control_table为新建行存表,只有一个字段,字段的取值为要更新的目标表名。 在并发更新同一张目标表时,首先会利用这张表获取对应记录的行级锁,其他并发任务等待行级锁释放;等到前序事务提交完成后,释放control_table的行级锁,后序事务获取行存表的行锁后,再提交update列存表语句。通过这种方式实现delete/update语句的串行执行,避免并发更新的锁超时报错。 # 五、问题总结 并发update/delete在分布式环境比较常见,如果业务不想产生等锁报错可以串行执行。
  • [技术干货] 2022年 数据工程的现状!
    2022 年数据工程现状地图01 数据采集这一层包括流技术和 SaaS 服务,提供从业务系统到数据存储的管道。这方面值得一提的进展是 Airbyte 的戏剧性崛起。Airbyte 成立于 2020 年,在这年年底才转向其当前的产品。Airbyte 是一个开源项目,目前有超过 15000 家公司在使用。其社区有超过 600 名贡献者。在采用和社区方面,如此指数级的增长非常罕见。Airbyte 刚刚推出了他们的商业产品,并通过收购 Grouparoo(一个反向 ETL 连接器开源项目)扩展到反向 ETL(一个在数据工程现状地图中没有涉及的类别)。我们认为,反向 ETL 是一个与 ETL 有很大差别的产品,因为它需要将数据集成到业务系统中,帮助用户完成该系统中的工作流。我们很想知道事情的结果如何。02 数据湖2021 年,我们将数据仓库和湖仓(lakehouse)作为数据湖层的一部分。但今年,我们决定保留数据湖这个类别,仅指用作数据湖的对象存储技术。我们将所有的数据仓库和湖仓移至分析引擎类别。为什么?如今,数据工程师处理的大多数架构都很复杂,足以同时包括对象存储和分析引擎。因此,你要么只需要一个分析数据库(这种情况没有数据湖,只有一个作为分析引擎的数据仓库),要么两者都要。而当两者都需要时,你通常会在对象存储上执行一些分析,在分析引擎上执行另一些分析。这就是为什么它们需要很容易搭配使用。这种依赖关系发生在不同的层。大型数据集会托管在对象存储中,而工件和服务层数据集将存储在分析引擎和数据库中。在我们知道的架构中,没有看到一个征服另一个的情况。我们看到,在现实中,这些解决方案是并存的。这种架构产生的背后有多种原因,但其中一个肯定是成本考虑。在 Snowflake 或 BigQuery 中查询大量的数据是很昂贵的。因此,与其让分析数据库管理整个湖,不如在对象存储中管理一切它可以管理的东西,在它上面执行计算更便宜,而将所有必须由分析引擎管理的东西交给分析引擎。我们认为,湖仓是一个分析引擎(尽管在 Databricks 中,它既包括数据湖,也包括分析引擎)。这个架构的特点是使用 Spark SQL 的优化版本在 Delta 表格式上创建一个分析引擎。这提供了人们希望从分析引擎获得的性能和成本。同样的规则适用于 Iceberg 上的 Dremio,或支持将 Iceberg 作为数据库外部表的 Snowflake。03 元数据管理在元数据领域发生了很多事情!元数据的两个层次——这一层和图表顶部的组织层——正成为许多组织的关注点。回顾我们作为可扩展数据从业者所面临的挑战,在过去十年中,我们一直在围绕存储和计算机进行创新——所有这些都是为了确保它们支持数据的扩展。如今,我们面临的主要是可管理性问题,我们可以通过生成和管理元数据来解决这些问题。这一层涉及元数据的不同方面,让我们逐个看下。1、开放式表格式我们看到,在过去的一年里,开放式表格式取得了有趣的进步。它们正在成为数据湖中保存结构化数据的标准。一年之前,Delta Lake 是一个 Databricks 项目,它有一个商业化产品叫 Delta。然后在今年,Onehouse 公司商业化了 Apache Hudi,Tabular 公司商业化了 Apache Iceberg。这两家公司都是由这些开源项目的创建者创立的。因此,整个领域从开源变成了完全由商业实体支撑。这让人不禁会问,既然背后有商业利益,其他参与者对开源项目还能有多大影响。由于这三个开源项目都属于 Apache/Linux 基金会,所以对社区而言风险很低。这似乎并不能平息这三个项目的创建者和粉丝之间的激烈争论,围绕谁“真正”开源以及谁提供了最好的解决方案。Netflix 很快就会把这个故事作为电视剧的绝佳素材。2、Metastore 的未来仍不明朗……我们看到,Hive Metastore 被从架构中移除,开放式表格式或许可以替代它。并不是所有的组织都充分利用了 Metastore 的能力,如果他们唯一的用例是虚拟化表,那么开放式表格式和以它为基础构建的商业产品提供了一个很好的选择。Metastore 的其他用例还没有更好的替代解决方案。3、Git For DataGit For Data 的概念在社区中日渐流行。dbt 鼓励分析师在不同版本的数据(开发、过渡和生产)上使用最佳实践,但不支持在数据湖中创建和维护这些数据集。数据运营团队越来越需要提供跨组织的数据版本控制,以管理随着时间推移做过不同修订的数据集。对一个数据集进行不同修订的例子有:重新计算,这是算法和 ML 模型所必需的,或者是来自运营系统的回填,这在 BI 中经常发生,或者是遵循 GDPR 被遗忘权规定而删除一个子集。这一趋势从 LakeFS 及其社区的急剧增长可以明显看出来,我亲眼目睹了这一点。LakeFS 同时提供了结构化和非结构化数据操作服务,在两者都存在的情况下大放光彩。遗憾的是,关于 Dremio 的 Nessie 项目的使用情况,很难找到公开数据。有趣的是,它还提供了一个名为 Arctic 的免费服务。这可能是为了与 Tabular 竞争而做出的战略决定。04 数据计算为了更好地反映生态系统现状,我们今年对计算层做了一些修改。首先,我们完全删除了虚拟化这个类别。它目前似乎还没有流行开来。然后我们把计算引擎分成两类:分布式计算和分析引擎。它们之间的主要区别在于这些工具对其存储层的要求。分布式计算包括对存储没有要求的计算引擎,而分析引擎类别包含有要求的计算引擎(无论是否分布式)。1、分布式计算一般的分布式计算引擎允许工程师分发任意 SQL 或任何其他代码。当然,它们可能对编程语言有要求,但它们会在(通常是)联合数据上进行普遍分发。这可能是跨许多格式和数据源的数据。分布式计算类别中新增了两个有趣的补充:Ray 和 Dask。Ray 是一个开源项目,允许工程师扩展任何计算密集型的 Python 工作负载,主要用于机器学习。Dask 也是一个基于 Pandas 的分布式 Python 引擎。你可能认为,Spark 将是统治这个领域的分布式引擎,看不到任何竞争。因此,见证新技术在这一类别中的崛起还是相当令人兴奋的。2、分析引擎分析引擎类别包括所有的数据仓库,如 Snowflake、BigQuery、Redshift、Firebolt 以及老好的 PostgreSQL。它还包含像 Databricks lakehouse、Dremio 或 Apache Pinot 这样的湖仓。所有这些工具都有自己支持的数据格式,为的是使查询引擎提供更好的性能。由于所有的分析引擎都使用数据湖作为深层存储或存储,所以值得一提的是,Snowflake 现在支持将 Apache Iceberg 作为外部表格式之一,可以由 Snowflake 直接从湖中读取。 05 数据编排和可观察性这是今年新增加的一层,但由现有的类别组成。编排工具去年是元数据层的一部分,但我们把它移到了它真正属于的计算引擎层——它主要是跨计算引擎和数据源编排管道。与此同时,我们看到,可观察性工具在 2021 年有了很大的发展,可以支持更多的数据源(产生于任何计算引擎)。1、数据编排关于数据编排,有什么引人注目的事情发生吗?Airflow 仍然是最大的开源产品。从加入云计算行列至今,Astronomer 多年来一直以它为基础。现在,Astronomer 直接与云供应商在托管 Airflow 领域展开了竞争。Astronomer 另一个非常有趣的举动是收购了提供数据谱系的 Datakin。这让人不禁要问——当一个编排工具具备了数据谱系能力时会发生什么?理论上,这可以帮助数据团队构建更安全、更有弹性的管道。了解哪些数据集依赖于缺失、损坏或低质量的数据,将逻辑(由编排工具管理)和它们的输出(由谱系工具管理)联系起来,影响分析将变得相当容易。这是否会成为编排生态系统的一个组成部分,还有待观察。2、可观察性这个类别由 Monte Carlo 数据公司创建,也由它主导。Monte Carlo 的频繁融资表明其产品在市场上被迅速采用。该产品不断发展,提供了更多的集成(如 Databricks 生态系统),以及额外的可观察性和根源分析功能。或许正是这种成功推动了这一类别的增长,至少从如今在探索这一领域的公司数量来看是如此。2021 年,有几家公司成立或打破隐身状态,最有趣的是 Elementary,又一个来自 YC 的开源项目。06 数据科学和分析的可用性这一层是为数据架构(通过前几层创建)用户准备的:数据科学家和分析师,他们从数据获取洞察力。我们把这个类别分成三个子类别:端到端 MLOps 工具以数据中心化 ML 方法为基础的工具ML 可观察性和监控1、端到端 MLOps 工具当我着手考察这个领域时,有人告诉我,我应该把这个类别命名为:“准备好失望吧”。虽然这个类别有很棒的工具,但没有一个是真正的端到端。它们为 ML 过程中的某些步骤提供了很好的解决方案,但对 ML 管道的其他方面缺乏支持。尽管如此,提供端到端解决方案的方法在 2021 年还是很受欢迎。有几款面向特定任务的工具走上了这一道路,成为了端到端的产品,如 Comet、Weights & Biases、Clear.ml 和 Iguazio。2、数据中心化 ML这个子类别也没有逃脱端到端的陷阱,但其中列出的工具采用了不同的方法来提供功能。它们以数据及其管理作为任务的中心。这个领域有两个新成员 Activeloop 和 Graviti。它们是由经验丰富的数据从业者构建的,他们了解数据管理对数据操作成功的重要性。在 LakeFS,我们也有这样的感受。DagsHub 采取了一种独特的方法,提供了一个以数据为中心的端到端解决方案,不过是基于开源解决方案。他们在 ML 生命周期的每个阶段都很出色,提供了很好的可用性,并且易于集成。在这样一个混乱的领域里,这是一个可靠的方法,可以得到一个不错的端到端解决方案,同时也可以取悦用户。我们正满心期待地看着这家公司....3、ML 可观察性和监控这个子类别包括专注于模型质量监控和可观察性的工具。与数据可观察性类别非常相似,这一领域正在成长并逐步形成良好的发展势头。2022 年初,Deepchecks 开放了源代码,并迅速获得关注,吸引了不少贡献者和合作伙伴。4、Notebooks在 Notebooks 类别中,我们看到,得益于 Databricks 和 Snowflake 的投资,Hex 得到了更多的关注和验证。Hex 在其 Notebook 中提供了更多编排能力。Ploomber 也是如此,它的出现为 Jupyter 提供了编排能力。在过去的一年里,这个面向分析师的工具类别确立了自己的地位,并赢得了一些竞争。dbt 证明了自己是分析师的标准。2021 年,它发布了与可扩展数据工程栈的集成,包括对象存储、HMS 和 Databricks 的产品。在与生态系统合作的同时,2021 年,Databricks 推出了其“活性表”产品的正式版本,与 dbt 展开了直接竞争。 07 数据目录、权限和治理对于这个生态系统,我的感觉是,现在各种规模的公司对数据目录的需求都很明确。我们将看到,它会成为一种标准。基于开源项目的商业产品显示出良好的采用水平。与此同时,企业解决方案的长期供应商,Alation 和 Collibra,继续扩展他们的产品。而安全和权限管理供应商 BigID 也在试图提供一个目录。Immuta 继续致力于数据访问控制,其独特的技术使它现在可以兼容更多的数据源。为了加速发展,该公司早在 2021 年中期就完成了 9000 万美元的 D 轮融资。08 小结虽然该领域的公司数量在不断增加,但可以看到,其中有几个类别的产品出现了整合迹象。MLOps 趋向于端到端,Notebook 正在进入编排领域,而编排正在转向数据谱系和可观察性。与此同时,我们看到,开放式表格式进入了元存储功能。而在治理层,安全和权限管理工具进入目录领域,反之亦然......这些迹象是否预示着市场(仍然)有限,也许是 MLOps 市场有限?这种整合是否反映了由于激烈的竞争而产生的差异化需求(在编排方面可能是这种情况)?还是说这是一个填补空白的机会,像开放式表格或数据中心化 ML 那样的情况?还是说,这都是因为用户希望使用更少的工具来做更多的事情?我打算把这些问题留给读者,希望能引发对 2022 年数据工程状况的讨论。2022 年,还有哪些项目正在获得发展的动力?哪些工具正在成为行业内的事实标准?欢迎在评论区分享您的想法。来源:InfoQ    https://lakefs.io/the-state-of-data-engineering-2022
  • [知识分享] 解读Go分布式链路追踪实现原理
    【摘要】 在分布式、微服务架构下,应用一个请求往往贯穿多个分布式服务,这给应用的故障排查、性能优化带来新的挑战。分布式链路追踪作为解决分布式应用可观测问题的重要技术,愈发成为分布式应用不可缺少的基础设施。本文将详细介绍分布式链路的核心概念、架构原理和相关开源标准协议,并分享我们在实现无侵入 Go 采集 Sdk 方面的一些实践。 为什么需要分布式链路追踪系统 微服务架构给运维、排障带来新挑战在分布式架构...本文分享自华为云社区《一文详解|Go 分布式链路追踪实现原理》,作者:开源小E。在分布式、微服务架构下,应用一个请求往往贯穿多个分布式服务,这给应用的故障排查、性能优化带来新的挑战。分布式链路追踪作为解决分布式应用可观测问题的重要技术,愈发成为分布式应用不可缺少的基础设施。本文将详细介绍分布式链路的核心概念、架构原理和相关开源标准协议,并分享我们在实现无侵入 Go 采集 Sdk 方面的一些实践。为什么需要分布式链路追踪系统微服务架构给运维、排障带来新挑战在分布式架构下,当用户从浏览器客户端发起一个请求时,后端处理逻辑往往贯穿多个分布式服务,这时会浮现很多问题,比如:请求整体耗时较长,具体慢在哪个服务?请求过程中出错了,具体是哪个服务报错?某个服务的请求量如何,接口成功率如何?回答这些问题变得不是那么简单,我们不仅仅需要知道某一个服务的接口处理统计数据,还需要了解两个服务之间的接口调用依赖关系,只有建立起整个请求在多个服务间的时空顺序,才能更好的帮助我们理解和定位问题,而这,正是分布式链路追踪系统可以解决的。分布式链路追踪系统如何帮助我们分布式链路追踪技术的核心思想:在用户一次分布式请求服务的调⽤过程中,将请求在所有子系统间的调用过程和时空关系追踪记录下来,还原成调用链路集中展示,信息包括各个服务节点上的耗时、请求具体到达哪台机器上、每个服务节点的请求状态等等。如上图所示,通过分布式链路追踪构建出完整的请求链路后,可以很直观地看到请求耗时主要耗费在哪个服务环节,帮助我们更快速聚焦问题。同时,还可以对采集的链路数据做进一步的分析,从而可以建立整个系统各服务间的依赖关系、以及流量情况,帮助我们更好地排查系统的循环依赖、热点服务等问题。分布式链路追踪系统架构概览核心概念在分布式链路追踪系统中,最核心的概念,便是链路追踪的数据模型定义,主要包括 Trace 和 Span。其中,Trace 是一个逻辑概念,表示一次(分布式)请求经过的所有局部操作(Span)构成的一条完整的有向无环图,其中所有的 Span 的 TraceId 相同。Span 则是真实的数据实体模型,表示一次(分布式)请求过程的一个步骤或操作,代表系统中一个逻辑运行单元,Span 之间通过嵌套或者顺序排列建立因果关系。Span 数据在采集端生成,之后上报到服务端,做进一步的处理。其包含如下关键属性:Name:操作名称,如一个 RPC 方法的名称,一个函数名StartTime/EndTime:起始时间和结束时间,操作的生命周期ParentSpanId:父级 Span 的 IDAttributes:属性,一组 <K,V> 键值对构成的集合Event:操作期间发生的事件SpanContext:Span 上下文内容,通常用于在 Span 间传播,其核心字段包括 TraceId、SpanId一般架构分布式链路追踪系统的核心任务是:围绕 Span 的生成、传播、采集、处理、存储、可视化、分析,构建分布式链路追踪系统。其一般的架构如下如所示:我们看到,在应用端需要通过侵入或者非侵入的方式,注入 Tracing Sdk,以跟踪、生成、传播和上报请求调用链路数据;Collect agent 一般是在靠近应用侧的一个边缘计算层,主要用于提高 Tracing Sdk 的写性能,和减少 back-end 的计算压力;采集的链路跟踪数据上报到后端时,首先经过 Gateway 做一个鉴权,之后进入 kafka 这样的 MQ 进行消息的缓冲存储;在数据写入存储层之前,我们可能需要对消息队列中的数据做一些清洗和分析的操作,清洗是为了规范和适配不同的数据源上报的数据,分析通常是为了支持更高级的业务功能,比如流量统计、错误分析等,这部分通常采用flink这类的流处理框架来完成;存储层会是服务端设计选型的一个重点,要考虑数据量级和查询场景的特点来设计选型,通常的选择包括使用 Elasticsearch、Cassandra、或 Clickhouse 这类开源产品;流处理分析后的结果,一方面作为存储持久化下来,另一方面也会进入告警系统,以主动发现问题来通知用户,如错误率超过指定阈值发出告警通知这样的需求等。刚才讲的,是一个通用的架构,我们并没有涉及每个模块的细节,尤其是服务端,每个模块细讲起来都要很花些功夫,受篇幅所限,我们把注意力集中到靠近应用侧的 Tracing Sdk,重点看看在应用侧具体是如何实现链路数据的跟踪和采集的。协议标准和开源实现刚才我们提到 Tracing Sdk,其实这只是一个概念,具体到实现,选择可能会非常多,这其中的原因,主要是因为:不同的编程语言的应用,可能采用不同技术原理来实现对调用链的跟踪不同的链路追踪后端,可能采用不同的数据传输协议当前,流行的链路追踪后端,比如 Zipin、Jaeger、PinPoint、Skywalking、Erda,都有供应用集成的 sdk,导致我们在切换后端时应用侧可能也需要做较大的调整。社区也出现过不同的协议,试图解决采集侧的这种乱象,比如 OpenTracing、OpenCensus 协议,这两个协议也分别有一些大厂跟进支持,但最近几年,这两者已经走向了融合统一,产生了一个新的标准 OpenTelemetry,这两年发展迅猛,已经逐渐成为行业标准。OpenTelemetry 定义了数据采集的标准 api,并提供了一组针对多语言的开箱即用的 sdk 实现工具,这样,应用只需要与 OpenTelemetry 核心 api 包强耦合,不需要与特定的实现强耦合。应用侧调用链跟踪实现方案概览应用侧核心任务应用侧围绕 Span,有三个核心任务要完成:生成 Span:操作开始构建 Span 并填充 StartTime,操作完成时填充 EndTime 信息,期间可追加 Attributes、Event 等传播 Span:进程内通过 context.Context、进程间通过请求的 header 作为 SpanContext 的载体,传播的核心信息是 TraceId 和 ParentSpanId上报 Span:生成的 Span 通过 tracing exporter 发送给 collect agent / back-end server要实现 Span 的生成和传播,要求我们能够拦截应用的关键操作(函数)过程,并添加 Span 相关的逻辑。实现这个目的会有很多方法,不过,在罗列这些方法之前,我们先看看在 OpenTelemetry 提供的 go sdk 中是如何做的。基于 OTEL 库实现调用拦截OpenTelemetry 的 go sdk 实现调用链拦截的基本思路是:基于 AOP 的思想,采用装饰器模式,通过包装替换目标包(如 net/http)的核心接口或组件,实现在核心调用过程前后添加 Span 相关逻辑。当然,这样的做法是有一定的侵入性的,需要手动替换使用原接口实现的代码调用改为包装接口实现。我们以一个 http server 的例子来说明,在 go 语言中,具体是如何做的:假设有两个服务 serverA 和 serverB,其中 serverA 的接口收到请求后,内部会通过 httpclient 进一步发起到 serverB 的请求,那么 serverA 的核心代码可能如下图所示:以 serverA 节点为例,在 serverA 节点应该产生至少两个 Span:Span1,记录 httpServer 收到一个请求后内部整体处理过程的一个耗时情况Span2,记录 httpServer 处理请求过程中,发起的另一个到 serverB 的 http 请求的耗时情况并且 Span1 应该是 Span2 的 ParentSpan我们可以借助 OpenTelemetry 提供的 sdk 来实现 Span 的生成、传播和上报,上报的逻辑受篇幅所限我们不再详述,重点来看看如何生成这两个 Span,并使这两个 Span 之间建立关联,即 Span 的生成和传播 。HttpServer Handler 生成 Span 过程对于 httpserver 来讲,我们知道其核心就是 http.Handler 这个接口。因此,可以通过实现一个针对 http.Handler 接口的拦截器,来负责 Span 的生成和传播。package http type Handler interface { ServeHTTP(ResponseWriter, *Request) } http.ListenAndServe(":8090", http.DefaultServeMux)要使用 OpenTelemetry Sdk 提供的 http.Handler 装饰器,需要如下调整 http.ListenAndServe 方法:import ( "net/http" "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/sdk/trace" "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp" ) wrappedHttpHandler := otelhttp.NewHandler(http.DefaultServeMux, ...) http.ListenAndServe(":8090", wrappedHttpHandler)如图所示,wrppedHttpHandler 中将主要实现如下逻辑(精简考虑,此处部分为伪代码):① ctx := tracer.Extract(r.ctx, r.Header):从请求的 header 中提取 traceparent header 并解析,提取 TraceId和 SpanId,进而构建 SpanContext 对象,并最终存储在 ctx 中;② ctx, span := tracer.Start(ctx, genOperation(r)):生成跟踪当前请求处理过程的 Span(即前文所述的Span1),并记录开始时间,这时会从 ctx 中读取 SpanContext,将 SpanContext.TraceId 作为当前 Span 的TraceId,将 SpanContext.SpanId 作为当前 Span的ParentSpanId,然后将自己作为新的 SpanContext 写入返回的 ctx 中;③ r.WithContext(ctx):将新生成的 SpanContext 添加到请求 r 的 context 中,以便被拦截的 handler 内部在处理过程中,可以从 r.ctx 中拿到 Span1 的 SpanId 作为其 ParentSpanId 属性,从而建立 Span 之间的父子关系;④ span.End():当 innerHttpHandler.ServeHTTP(w,r) 执行完成后,就需要对 Span1 记录一下处理完成的时间,然后将它发送给 exporter 上报到服务端。HttpClient 请求生成 Span 过程我们再接着看 serverA 内部去请求 serverB 时的 httpclient 请求是如何生成 Span 的(即前文说的 Span2)。我们知道,httpclient 发送请求的关键操作是 http.RoundTriper 接口:package http type RoundTripper interface { RoundTrip(*Request) (*Response, error) }OpenTelemetry 提供了基于这个接口的一个拦截器实现,我们需要使用这个实现包装一下 httpclient 原来使用的 RoundTripper 实现,代码调整如下:import ( "net/http" "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/sdk/trace" "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp" ) wrappedTransport := otelhttp.NewTransport(http.DefaultTransport) client := http.Client{Transport: wrappedTransport}如图所示,wrappedTransport 将主要完成以下任务(精简考虑,此处部分为伪代码):① req, _ := http.NewRequestWithContext(r.ctx, “GET”,url, nil) :这里我们将上一步 http.Handler 的请求的 ctx,传递到 httpclient 要发出的 request 中,这样在之后我们就可以从 request.Context() 中提取出 Span1 的信息,来建立 Span 之间的关联;② ctx, span := tracer.Start(r.Context(), url):执行 client.Do() 之后,将首先进入 WrappedTransport.RoundTrip() 方法,这里生成新的 Span(Span2),开始记录 httpclient 请求的耗时情况,与前文一样,Start 方法内部会从 r.Context() 中提取出 Span1 的 SpanContext,并将其 SpanId 作为当前 Span(Span2)的 ParentSpanId,从而建立了 Span 之间的嵌套关系,同时返回的 ctx 中保存的 SpanContext 将是新生成的 Span(Span2)的信息;③ tracer.Inject(ctx, r.Header):这一步的目的是将当前 SpanContext 中的 TraceId 和 SpanId 等信息写入到 r.Header 中,以便能够随着 http 请求发送到 serverB,之后在 serverB 中与当前 Span 建立关联;④ span.End():等待 httpclient 请求发送到 serverB 并收到响应以后,标记当前 Span 跟踪结束,设置 EndTime 并提交给 exporter 以上报到服务端。基于 OTEL 库实现调用链跟踪总结我们比较详细的介绍了使用 OpenTelemetry 库,是如何实现链路的关键信息(TraceId、SpanId)是如何在进程间和进程内传播的,我们对这种跟踪实现方式做个小的总结:如上分析所展示的,使用这种方式的话,对代码还是有一定的侵入性,并且对代码有另一个要求,就是保持 context.Context 对象在各操作间的传递,比如,刚才我们在 serverA 中创建 httpclient 请求时,使用的是http.NewRequestWithContext(r.ctx, ...) 而非http.NewRequest(...)方法,另外开启 goroutine 的异步场景也需要注意 ctx 的传递。非侵入调用链跟踪实现思路我们刚才详细展示了基于常规的一种具有一定侵入性的实现,其侵入性主要表现在:我们需要显式的手动添加代码使用具有跟踪功能的组件包装原代码,这进一步会导致应用代码需要显式的引用具体版本的 OpenTelemetry instrumentation 包,这不利于可观测代码的独立维护和升级。那我们有没有可以实现非侵入跟踪调用链的方案可选?所谓无侵入,其实也只是集成的方式不同,集成的目标其实是差不多的,最终都是要通过某种方式,实现对关键调用函数的拦截,并加入特殊逻辑,无侵入重点在于代码无需修改或极少修改。上图列出了现在可能的一些无侵入集成的实现思路,与 .net、java 这类有 IL 语言的编程语言不同,go 直接编译为机器码,导致无侵入的方案实现起来相对比较麻烦,具体有如下几种思路:编译阶段注入:可以扩展编译器,修改编译过程中的ast,插入跟踪代码,需要适配不同编译器版本。启动阶段注入:修改编译后的机器码,插入跟踪代码,需要适配不同 CPU 架构。如 monkey, gohook。运行阶段注入:通过内核提供的 eBPF 能力,监听程序关键函数执行,插入跟踪代码,前景光明!如,tcpdump,bpftrace。Go 非侵入链路追踪实现原理Erda 项目的核心代码主要是基于 golang 编写的,我们基于前文所述的 OpenTelemetry sdk,采用基于修改机器码的的方式,实现了一种无侵入的链路追踪方式。前文提到,使用 OpenTelemetry sdk 需要代码做一些调整,我们看看这些调整如何以非侵入的方式自动的完成:我们以 httpclient 为例,做简要的解释。gohook 框架提供的 hook 接口的签名如下:// target 要hook的目标函数 // replacement 要替换为的函数 // trampoline 将源函数入口拷贝到的位置,可用于从replcement跳转回原target func Hook(target, replacement, trampoline interface{}) error对于 http.Client,我们可以选择 hook DefaultTransport.RoundTrip() 方法,当该方法执行时,我们通过 otelhttp.NewTransport() 包装起原 DefaultTransport 对象,但需要注意的是,我们不能将 DefaultTransport 直接作为 otelhttp.NewTransport() 的参数,因为其 RoundTrip() 方法已经被我们替换了,而其原来真正的方法被写到了 trampoline 中,所以这里我们需要一个中间层,来连接 DefaultTransport 与其原来的 RoundTrip 方法。具体代码如下://go:linkname RoundTrip net/http.(*Transport).RoundTrip //go:noinline // RoundTrip . func RoundTrip(t *http.Transport, req *http.Request) (*http.Response, error) //go:noinline func originalRoundTrip(t *http.Transport, req *http.Request) (*http.Response, error) { return RoundTrip(t, req) } type wrappedTransport struct { t *http.Transport } //go:noinline func (t *wrappedTransport) RoundTrip(req *http.Request) (*http.Response, error) { return originalRoundTrip(t.t, req) } //go:noinline func tracedRoundTrip(t *http.Transport, req *http.Request) (*http.Response, error) { req = contextWithSpan(req) return otelhttp.NewTransport(&wrappedTransport{t: t}).RoundTrip(req) } //go:noinline func contextWithSpan(req *http.Request) *http.Request { ctx := req.Context() if span := trace.SpanFromContext(ctx); !span.SpanContext().IsValid() { pctx := injectcontext.GetContext() if pctx != nil { if span := trace.SpanFromContext(pctx); span.SpanContext().IsValid() { ctx = trace.ContextWithSpan(ctx, span) req = req.WithContext(ctx) } } } return req } func init() { gohook.Hook(RoundTrip, tracedRoundTrip, originalRoundTrip) }我们使用 init() 函数实现了自动添加 hook,因此用户程序里只需要在 main 文件中 import 该包,即可实现无侵入的集成。值得一提的是 req = contextWithSpan(req) 函数,内部会依次尝试从 req.Context() 和 我们保存的 goroutineContext map 中检查是否包含 SpanContext,并将其赋值给 req,这样便可以解除了必须使用 http.NewRequestWithContext(...) 写法的要求。详细的代码可以查看 Erda 仓库:https://github.com/erda-project/erda-infra/tree/master/pkg/trace参考链接https://opentelemetry.io/registry/https://opentelemetry.io/docs/instrumentation/go/getting-started/https://www.ipeapea.cn/post/go-asm/https://github.com/brahma-adshonor/gohookhttps://www.jianshu.com/p/7b3638b47845https://paper.seebug.org/1749/
  • [技术干货] 十图纵览2022年中国数据库产品策略报告
    头豹研究院在2022年6月发布了,《2022年中国数据库产品策略解析报告》,对中国数据库产品技术进行了分析探讨,其中的技术总结值得一览,本文摘要进行分享。1、数据模型是数据库系统的核心和基础,各种数据库都是基于不同的数据模型而生的, 对数据库技术发展阶段的划分基本按照数据模型的发展演变作为主要依据和标志。评注:数据模型分类法,是数据库进行分类的第一个维度,墨天轮排行榜即按此作为第一分类。2、数据库设计理论和流程:对于给定的应用环境,构造最优的数据库模式,建立数据库及其应用系统, 使之能够有效地存储数据,并满足各种用户对信息分类与处理等应用要求。数据库设计理论正在寻求更有效的语义表达关系,并在各设计阶段提供自动或半自动的设计工具和集成化的开发环境。3、数据库产品发展思路与增长路径全瞻观察数据库有两个视角,分别是技术视角、应用视角。从技术视角,是数据模型、并发控制、一致性;从应用视角,是电信应用、金融高可用、灾备切换。这两个视角在技术基础层上汇对融合。4、中国数据库代表厂商 - 中国数据库厂商分为传统数据库厂商、新兴数据库厂商、云 厂商、ICT跨界厂商四类,各家提供不同的集中式数据库与分 布式数据库产品.5、分布式事务处理技术 - 在分布式架构领域中存在一则指导纲领:CAP理论,指出一个数据库系统无法同时实现以下三个目标,只能妥协其一选余二。1. 提升系统的可用性;2. 保证数据的实时可见;3. 提升系统的容错能力。CAP理论是学界中的概念化描述,在工程实践中,存在不同的思路和实践产品在摸索CAP理论中三者共存的边界。其中应用了包括不同的架构、 事务解决方案、加锁机制、隔离机制、一致性算法/协议。学界也提出了 PACELC理论等持续探索更优的分布式系统架构模式。6、数据库事务原则在CAP理论的提出后,分布式与事务型数据库开始结合。分布式一致性和 事务一致性的融合,简化了应用层开发者的研发负担,不需要开发者精通分布式一致性和事务一致性的全部语义,以此提高了工作效率。BASE原则使得分布式系统的多个组件的协作能够以弱耦合的方式形成一个异步系统,将理论推导和工程实现变得更简单。但ACID原则尤其是满足强一致性依然是所有分布式数据库架构的目标。7、Paxos协议和Raft协议是分布式数据库的一致性算法中最为主流的协议方案.当前流行的一致性解决方案是:基于两阶段提交协议(2PC)实现跨shard 事务提交的完整性,基于全局唯一递增时间戳实现跨shard事务的全局读一致性,通过Paxos协议和或aft协议实现多副本之间的数据一致性。8、HTAP描述的是消除OLTP和OLAP之间的间隔,使一个数据库系统既可以应用于事务型数据库场景,又可以应用于分析型数据库场景,从而满足实时业务决策的需求。HTAP能让数据产生后马上就可以进入分析场景,目前HTAP有两种方案:分离架构和统一架构,分离架构是目前的主流方 案。趋势中,云原生架构环境与HTAP系统的融合将衍生新的HTAP产品方案和技术特征。9、数据库技术架构整体包括管理模块、计算模块和存储模块,物理资源层是为数据库提供基础支撑环境。四个模块中分别具有不同的前沿创新技术10、数据库产品选型决策树对数据库有采购、研发、应用等需求的企业可以从数据模型、 数据量和计算资源情况、业务需求等方面考量,选择适合自身场景需求的优势数据库产品。文章来源:数据和云
  • [圈层活动] 华为云分布式云原生技术与实践之路
    随着云原生应用深入企业各个业务场景,云原生正在走向分布式,跨云跨地域统一协同治理,保证一致应用体验等新的需求日渐突出。分布式云原生都涉及哪些核心技术?有哪些典型的应用场景?值得我们去探究。HCDE(Huawei Cloud Developer Experts)是经华为云认证的熟悉一种或多种华为云开放能力,并对赋能全球开发者有突出贡献的个人,旨在帮助全球开发者成长,构建全球开发者生态。2022年6月21日,华为云HCDE专场暨分布式技术峰会如期举行,华为云Karmada社区Maintainer任洪彩担任出品人,携手华为云分布式云架构师王楠楠,以及HCDE的代表成员——南京路特软件CTO戚俊、中韩未来革新加速器社长唐云峰、深圳市友浩达科技CTO张善友,共同分享了分布式云原生核心技术和典型应用。华为云分布式云原生的全域调度技术与实践华为云分布式云架构师王楠楠在分享中提到,华为云通过1个中心、3个核心能力,为应用从核心区到业务现场形成广泛覆盖,构建了应用全域分发、全域调度、智能安全、统一编排等多项核心技术。其中,1个中心是指提供对云原生基础设施、应用、用户权限、安全策略的一站式管理,3个核心能力是指应用算力供给、应用流量治理、应用与数据协同。云原生助力SaaS类业务租户高效隔离面对业务波动难以控制、无法实现精准计费等租户隔离的难点,南京路特软件CTO戚俊提出了通过云原生架构改造隔离逻辑,并结合华为云服务平抑容器类业务波动、实现精准计费的操作方案。从“AI玩具”到“创作工具”的云原生改造之路理想的AI创作工具长什么样?中韩未来革新加速器社长唐云峰认为需具备这些功能特点:在线部署、按量付费、随时可用、垫图绘画、并行创作、持续交付、弹性扩展。唐云峰基于华为云进行了尝试,并将算子工作流程归纳为:1、上传图片到OBS指定存储桶后触发函数计算;2、函数计算调度从SWR托管的镜像创建CCI实例;3、在CCI实例中将上传图像作为“垫图”配合“描述文本”生成多个参数的并行GPU实例;4、进行绘制将生成完成的图像和视频存储到结果存储桶中。基于Kubernetes与Dapr打造云原生应用谈及分布式应用架构的演进,深圳市友浩达科技CTO张善友分享了三个观点:1、Spring Cloud武器库迷局:超过30个子项目,对前期应用和后期维护均造成一定困难;2、以Istio为代表服务网格日趋成熟;3、以Dapr为代表的多运行时很好的融合了框架和网格。随后,张善友对Dapr进行了重点介绍。Dapr是一个开源解决方案,主要设计目标是可移植性,同时提供了标准API、语言SDK和Runtime,需要应用进行适配,并且提供各种分布式能力助力应用的现代化。通过几位华为云MVP的精彩分享后,华为云HCDE专场暨分布式技术峰会顺利落下了帷幕。华为云致力于搭建技术交流平台、机遇共创的通道,全面助力每一位开发者、每一位合作伙伴,期待下期活动再次相会。如想了解参加更多华为云HCDE相关活动或有合作需求请联系小助手(微信号:hwyzj123)