-
如何优化分布式系统的性能和响应速度?
-
一、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) { ...... } ```
-
摘要:全场景可扩展的分布式协同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 年数据工程现状地图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 采集 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年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)
-
>摘要:NFT是Web3世界中标记数据资产独特性的标识,是数据权益的载体。 本文分享自华为云社区《[加密数字艺术NFT背后你关心的六个问题](https://bbs.huaweicloud.com/blogs/358470?utm_source=csdn&utm_medium=bbs-ex&utm_campaign=other&utm_content=content)》,作者: 薛腾飞 。 # Connect Wallet 这是Web3中非常流行的一句话,其实也是Web3的核心要义,即“**以用户为中心**”。将身份主权、数据主权、数据权益等都归还给用户,身份的解释、移植,数据的确权、授权、使用等都需要各个服务通过“链接”用户的“钱包”来完成。以区块链为基础设施构筑上层应用,是实现这一能力的重要保障。 # 什么是NFT? 在我看来,**NFT是Web3世界中标记数据资产独特性的标识,是数据权益的载体**。不论是数字化的画作,桌椅、服装、汽车飞机等(有实物的),还是数字化的身份凭证、产权、公司品牌等(逻辑产物)都可以是NFT。 **独特性的标识为什么这么重要呢**?因为它能将其指代的物品和其他同类物品区分开。 为了进一步理解,首先要明确,有些物品是非同质的(Non-Fungible)需要被区分开的,例如房屋产权和艺术作品。有些物品是同质的,不需要被区分开,例如人民币和app积分,尽管有不同的编码,但编码不影响互相替换,因为面值一样;其次要区分开标识和标的物,标的物可以是区块链上原生的数据或者本身是数字化的,也可以是物理世界实际存在的物品,标识则是标的物在数字世界中的映射。 在数字世界中,“标识”将完成“标的物”独特性的指代和“标的物”价值承载的使命。例如一个艺术家将数字作品发布在社交平台,其作品会很快被复制多份,每一幅作品逐渐趋于同质化,没有区别。画作的价值也会越来越低,且没有人会知道画作的原作者是谁。但在Web3中,艺术家就可以通过NFT低成本的保证作品的独特性和价值,NFT中会有作品铸造时间、创建者、和当前所有者。只要是晚于铸造时间发布的都为抄袭者,画作所有权每次流转都可以承载不同的价值属性,无论流转多次都知道原作者谁。  # NFT能用来做什么? 海外市场NFT产业布局完善,行业竞争激烈。NFT以交易平台和时尚社交为主,NFT收藏、游戏、金融等同步发展。国内以数字藏品收藏和企业数字营销为主,逐步开始尝试数字人、游戏等。除此之外,NFT的应用场景还包括体育、文物和历史、音乐、票务等访问授权类。 ## 1.收藏品 稀缺性是收藏品的重要属性。区块链的不可篡改以及NFT本身的不可分割保证了数字藏品独特性。与球卡和邮票一样,数字收藏品的藏家会收藏他们认为有价值的数字产品以表示对某一公司、品牌或者游戏支持。有别于实物,无需运输时间,维护成本等开销。只需几秒完成转移,且永远不会折旧。CryptoPunks是以太坊上推出的最早的数字藏品NFT,类似的国内多家互联网平台联合博物馆、航天局等单位,发行了多款数字藏品,例如“故宫故苑”和“航天文创”。 ## 2.游戏 NFT是区块链游戏的基础,可以作为数字游戏世界中成就或游戏物品的所有权证书。移独一无二游戏物品(道具、头像、皮肤、角色等)归玩家所有,且无需托管,不受发行商控制。这些NFT的寿命会比游戏平台本身更长,一方面玩家可以永久收藏,另一方面也可以移植到游戏之外其他平台,实现游戏投入变现。 ## 3.数字营销 NFT“限量发行、独一无二”本身就是一种最好的饥饿营销手段,不定期的赋予每个NFT新的权益,发布新的玩法和活动也都是很好的营销策略。还可以基于NFT维护会员制度、增强用户粘性,完成破圈整合。国内有个很有趣、很有现实意义的的实践。福建省四坪村通过NFT吸引“云村民”并赋予权益,赋能乡村振兴。每一位数字藏品持有者可以作为村民享受多项权益,如享有家宴1次。不同时间不同事件还会解锁新的藏品及权益,丰富有趣。 ## 4.艺术品 在众多的艺术品中,我们以音乐为例,音乐产业是一个超级明星经济, 好的作品诞生涉及音乐人、唱片公司、娱乐公司、经纪人等。NFT可以帮助音乐人收益自主、拓宽收入来源;公平解决所有制作人员间的版税问题,交易中的数字所有权问题等。 除此之外,NFT音乐平台的用户运营,音乐演出的票务活动,知识产权保护等都已有很多创新项目在实践。 # 国内NFT技术产品有哪些? 随着NFT的火热,国内数字藏品发行平台百花齐放。据统计,其中注册资本大于500万的平台超过100家。市场繁荣的背后是几大技术供应商在提供底层区块链和NFT管理等相关技术能力,以联盟链为主,公链为辅。  # NFT 背的技术是什么? 知道了NFT是什么?能用来做什么?以及都有谁来参与之外,我们再来了解一下NFT背后的技术都有哪些。 ## 1.区块链 区块链是实现NFT的重要底座,赋予了NFT不可篡改、所有权明确、流转可追溯等特性。区块链融合了多种技术,包括密码学(加密算法、安全协议)、分布式共识算法(拜占庭或非拜占庭)、P2P网络通讯、智能合约、激励机制等。 应用的繁荣必将带动技术的生长。NFT应用的快速增长,大量用户接入区块链完成NFT的铸造发行、授权、流转等。这对传统的底层区块链提出了新的挑战和要求。 - 具备统一的链上用户身份标识,支持跨链、链跨应用的NFT所属权管理。 - 允许千级、万级节点接入,支持NFT平台发行方等加入链生态的构建与维护。 - 高吞吐,高并发的共识和记账能力,可以支撑NFT应用活动的峰值流量。 ## 2.智能合约协议 ERC(Ethereum Request for Common)“版本征求意见稿”是以太坊社区的开发者共同编写的,用来记录以太坊上应用级的各种开发标准和协议。其中一些技术标准和协议也逐渐成为了区块链应用的事实规范。 我们常提到的NFT就是在ERC-721标准提出后才开始普及流行的。ERC-721详细定义了NFT的所有权查看、授权管理、流转等。不同的数字藏品平台基于同样的协议完成设计,理论上就可以进行标准化的操作和解析。 随着对NFT的需求越来越丰富,社区也在不断提出新的标准来扩展NFT的使用场景和内涵:  ## 3. 去中心化存储 “一切皆可NFT”这句话从侧面表达了NFT对数字化数据的包容性。不论标的物是视频、音频、还是文字、图片、3D模型等各种数据格式,都可以在链上生成对应的唯一标识。标的物实际存储的位置通常有三种选择,NFT标识所在的业务区块链、去中心化存储系统、中心化的存储系统。  对于NFT而言,去中心化存储是最好的选择。它具有强隐私保护、低存储成本、高访问速度、数据冗余备份、开源等特点,可以充分的支撑Web3“以用户为中心”这一要义的表达。数据被加密并存储在多个位置或节点上,不依赖与中心化的存储节点和存储服务,下图可以极简的理解去中心化存储的工作原理。  值得关注和学习的几大去中心化存储产品有:  ## 4.应用生态 不难发现NFT发展背后的主要推动力就是用户对数据主权和数据价值自主控制意识的不断增强。构建完善的NFT应用生态,简单可以分为三层,身份协议层、 NFT合约协议层, 扩展应用协议层。 分布式数字身份真正具备身份的自主可控性、安全性、自解释性、可移植性、互操作性。在分布式场景下赋予每个用户自主控制和使用数字身份的能力,并针对身份数据等敏感信息进行隐私保护。基于分布式身份, NFT相关协议可以与多种扩展应用标准化集成。(详细了解可阅读《[区块链分布式身份技术解密——重新定义你的“身份”管理](https://bbs.huaweicloud.com/blogs/234838)》) 在标准化的身份协议层和NFT合约协议层之上,结合多样的业务场景定会生长出丰富的应用,例如可信数据交换、数据要素管理等。 # 如何发行自己的NFT 不论你是团队还是个人,想要发行自己的NFT都非常简单。 一种,是可以使用基于公链模式的数字自资产服务,支付手续费或者链使用费铸造发行NFT。例如支持多种公链的Opensea平台 另一种,可以使用基于联盟链模式的数字资产服务,订购服务通过集成SDK完成NFT的铸造发行及流转。例如[华为云的数字资产链服务](https://www.huaweicloud.com/product/bcs/dac.html)。
-
过去十年见证了分布式数据库的崛起不仅通过本地集群来实现负载均衡,并提供高可用性,还具有数据中心内的机架感知等属性。专为云而设计的分布式数据库,可以跨越可用性区域,通过编排技术,支持公有云、私有云、混合云部署。近年来,市面上出现了大量专为分布式数据库部署而设计的新数据库系统,以及在初始设计中添加了分布式架构组件的其他数据库系统。DB-Engines排名前100的数据库DB-Engines是数据库领域的权威排行榜,它保留了所有数据库的流行指数,使用一种算法进行加权,监测诸如网站上的提及次数和谷歌的搜索趋势,Stack Overflow上的讨论或推特中的评论,工作职位要求的技术技能,以及在LinkedIn个人资料中提到这些技术的数量。虽然DB-Engines收集了数百个不同的数据库(截至2022年5月共有394个)。但是本文我们缩小范围,只观察前100名数据库。在很大程度上,反映了市场现状。关系型数据库管理系统(RDBMS),传统的SQL系统,仍然是最大的类别,占列表的47%。另外,列表中有25%是NoSQL系统,涵盖了许多不同类型的数据库,像MongoDB文档数据库、Redis键值系统、ScyllaDB宽列数据库,以及Neo4j图数据库。还有11%的数据库被列为多模型数据库,包括在同一系统中支持SQL和NoSQL的混合数据库,如微软的Cosmos DB或ArangoDB,或者支持多种NoSQL数据模型的数据库,如DynamoDB,它将自己列为NoSQL键值系统和文档存储。最后,还有一些是由各种特殊用途的数据库组成,从搜索引擎到时间序列数据库,以及其他不容易归入简单的“SQL与NoSQL”区域的数据库。但是所有这些数据库都是分布式数据库吗?这个词到底是什么意思?分布式数据库的定义2016年12月14日,ISO/IEC发布了最新版本的数据库语言SQL标准(ISO/IEC9075:2016)。随着时间的推移,如何构建与SQL兼容的分布式RDBMS系统一直在发展。分布式SQL,如PostgreSQL或CockroachDB NewSQL系统。相反,没有ANSI或ISO或IETF或W3C定义什么是NoSQL数据库。每种数据库都使用自己的专有查询语言,比如用于宽列NoSQL数据库的Cassandra查询语言(CQL),用于图形数据库的Gremlin/Tinkerpop查询方法。然而,它们并没有定义数据如何在这些数据库中分布,查询语言也不能解决架构问题。因此,无论是SQL还是NoSQL,对于什么是分布式数据库,并没有标准、协议或共识。因此,我花了一些时间来写下我自己的定义。坦率地说,这更像是一个门外汉的实用主义观点,而不是计算机科学教授的见解。简而言之,你必须决定你如何定义集群,以及如何跨集群分配数据。接下来,你必须确定集群中每个节点的角色。每个节点都是对等的,还是有些节点处于更优越的领导地位,而其他节点则是跟随者。然后,基于这些角色,你如何处理故障转移?最后,你必须在此基础上,弄清楚你如何尽可能均匀和容易地复制和分片数据。而这并不试图做到详尽无遗,你可以添加自己的特定条件。简短的清单:感兴趣的系统考虑到这些,我在前100名数据库中,找到五个示例,看看它们在测量属性时是如何比较的。其中有两个SQL系统和三个NoSQL系统。Postgres和CockroachDB代表最好的分布式SQL。CockroachDB被称为 NewSQL,专为分布式数据库而设计。MongoDB、Redis和ScyllaDB是分布式NoSQL,分别是文档数据库,键值存储,宽列数据库(也被称为键值数据库)。在大多数情况下,适用于ScyllaDB的也同样适用于Apache Cassandra和其他与Cassandra兼容的系统。假定你拥有专业的经验,而且对SQL与NoSQL的区别相对了解。基本上,如果需要一个表JOIN,坚持使用SQL和RDBMS。如果你可以将数据反规范化,那么NoSQL可能是一个很好的选择。我们不打算讨论作为数据结构或查询语言,两者哪个“更好”。而是讨论作为一个分布式数据库,哪个更好。多数据中心集群我们的选项在集群方面是如何比较的?现在,它们都能够进行集群,甚至是多数据中心操作。但是在PostgreSQL、MongoDB和Redis中,它们最初设计于单数据中心本地集群,在多数据中心设计之前就已经成为一种架构要求。Postgres首次发布于1986年,完全早于云计算的概念。后来,它允许在其设计上,纳入这些技术和能力。作为NewSQL革命的一部分,CockroachDB从一开始就考虑到了全球分布。MongoDB是在公有云诞生之初发布的,最开始设计时考虑到了单数据中心集群,但现在已经增加了对许多不同拓扑结构的支持。通过MongoDB Atlas,可以轻松部署到多个地区。Redis,由于其低延迟的设计,通常被部署在单个数据中心,但它具有允许多数据中心部署的企业特性。ScyllaDB,像Cassandra一样,从一开始就考虑到了多数据中心的部署。集群管理如何进行复制和分片,取决于数据库架构的分层或同质化程度。例如,在MongoDB中,有一个主服务器,其余的是主服务器的副本。副本是只读的,你只能对这个数据库的主副本进行写操作,不能直接更新。相反,你写到主数据库,它就会更新副本。所以,节点是异质的,而不是同质的。这有助于在读取繁重的工作负载中分配流量,但在混合或写入工作负载中,对你没有一点好处,主服务器可能会成为一个瓶颈。同样,如果主服务器发生故障会怎样?你将不得不完全停止写操作,直到集群选出一个新的主服务器,并将写操作分流到它上面。相反,如果ScyllaDB或Cassandra,或任何其他无active-active的系统,客户可以从任何节点读取或写入。没有单一的故障点,节点的同质化程度要高得多。而且每个节点都可以更新集群中的任何数据副本。因此,如果你有三个节点,每个节点都会根据其他两个节点的任何写入进行更新。active-active在计算方面本身就比较困难,但是一旦解决了服务器保持彼此同步的问题,就会得到一个可以更好地平衡混合或写入大量工作负载的系统,因为每个节点都可以提供读取或写入服务。那么,我们的各种例子在主复本或active-active对等方面是如何叠加的?CockroachDB和ScyllaDB,以及Cassandra一开始就考虑了active-active的主动式设计。在Postgres中,有一些可选的方法可以做到这一点,但它不是内置的。此外,MongoDB没有正式支持active-active,但是已经有一些人在尝试如何做到这一点了。对于Redis来说,active-active模型在Redis企业中可以通过无冲突复制数据类型(CRDTs)实现。Postgres、MongoDB和Redis都默认使用主副本数据分布模型。复制分布式系统设计也会影响如何跨部署到不同机架或数据中心之间分配数据。例如,给定一个主副本系统,只具有主的数据中心可以为任何写入工作负载服务,其他数据中心只能作为只读副本。在一个支持多数据中心集群的点对点系统中,整个集群中的每个节点都可以接受读或写操作。通过ScyllaDB,你可以决定每个站点有相同或甚至不同的复制因素。这里我展示了在一个数据中心的三个副本,在另一个数据中心有两个副本的可能性。操作可以有不同级别的一致性。你可能在三个节点的数据中心进行本地数据的读或写,需要更新任一数据中心的节点才能成功执行操作。可调整的一致性,结合多数据中心的拓扑感知,为工作负载提供更多的灵活性。拓扑感知本地集群是分布式数据库开始的方式,允许多个系统共享负载。如果想让数据库在多个节点上进行分片,或者通过确保相同的数据在多个节点上可用来实现高可用性,那么这一点非常重要。如果所有节点都安装在同一个机架上,一旦这个机架发生故障,就会很棘手。因此,添加拓扑感知,以便你可以感知同一数据中心内的机架。确保将数据分散在数据中心的多个机架上,从而最大限度地减少电源或连接丢失到一个或另一个机架的中断。有些数据库做的很好,允许在不同的数据中心运行数据库的多个副本,并使用某种跨集群更新机制。每个数据库都是自主运行的,它们的同步机制可以是单向的,一个数据中心更新一个下游的副本,也可以是双向的或多向的。这种地理分布可以通过允许更靠近用户的连接,来减少延迟。跨可用性区域或地区的数据库,还可以确保单个数据中心灾难不会导致数据库的部分或全部丢失。去年我们的一个客户就发生了这种情况,但由于他们部署在三个不同的数据中心,所以数据损失为零。跨集群更新最初是在批量级别上实现的。确保你的数据中心每天至少有一次同步。这并没有持续多久,后面人们开始确保更活跃的事务级更新。如果你在运行强一致性数据库,就会受到基于光速的实时传播延迟的限制。因此,实现最终一致性是为了允许每个操作更新使用多数据中心,同时考虑到在短期内,要使所有数据中心的数据保持一致可能需要时间。那么,在拓扑感知方面,它是如何叠加的?所以,CockroachDB和ScyllaDB也是内置的。从2015年开始,拓扑感知也成为MongoDB的一部分,他们在这方面有着多年的经验。Postgres和Redis最初被设计为单数据中心解决方案,因此处理多数据中心的延迟对两者来说并非易事。现在,你可以添加拓扑感知,就像添加active-active系统功能一样,但它并不是开箱即用的。让我们回顾一下所讨论的内容,分别查看这些数据库的属性。▶︎ PostgreSQLPostgreSQL是世界上最流行的的开源数据库之一,它以可靠性和稳定性而著称,在处理复杂SQL方面也表现出了绝对的优势。然而,Postgres仍在研究其跨集群和多数据中心的集群。由于SQL基于强一致性事务模式,所以它不能很好地跨地域跨集群。在所有相关的数据中心之间,每个查询都将由于长时间的延迟而暂停。此外,Postgres依靠的是主副本模型。集群中的一个节点是领导者,而其他节点是副本。虽然有负载平衡器或active-active插件,但这些也超出了基本的服务范围。最后,Postgres的分片在大多数情况下仍然是手动的,尽管他们在开发自动分片方面取得了进展,但这也超出了基本产品的范围。▶︎ CockroachDBCockroachDB声称自己是“NewSQL”,一个专为分发而设计的SQL数据库。它可以水平扩展,在磁盘、机器、机架,甚至数据中心故障时都能生存下来,做到延迟最小,无需手动干预。值得一提的是,CockroachDB使用Postgres线协议,并大量借鉴了Postgres开创的许多概念,而且并不局限于Postgres的架构。多数据中心集群和点对点的拓扑结构从一开始就被内置。自动分片和数据复制也是如此。它还内置了数据中心感知功能,而且还可以添加机架感知功能。对CockroachDB来说,它要求所有的事务都有很强的一致性,你可以把它看作是一个优点或缺点。既没有最终一致性的灵活性,也没有可调的一致性。这将降低吞吐量,并在任何跨数据中心部署中要求较高的基线延迟。▶︎ MongoDBMongoDB是NoSQL领域的领导者。随着它的发展,大量的分布式数据库功能被添加。现如今,MongoDB能够支持多数据中心集群。在大多数情况下,它仍然遵循主副本模式,也有办法使其成为对等的active-active。▶︎ Redis接下来是Redis,一个旨在作为内存缓存或数据存储的键值存储。Redis的数据全部在内存里,如果突然宕机,数据就会全部丢失,因此必须有一种机制来保证Redis的数据不会因为故障而丢失,这种机制就是Redis的持久化机制。虽然持久化保存数据,但如果数据集不适合放在RAM中,它就会遭受巨大的性能损失。正因为如此,它在设计时考虑到了本地集群。如果你无法承受5毫秒的等待时间来从SSD上获取数据,您可能更无法等待145毫秒来完成从旧金山到伦敦的网络往返时间。然而,有一些企业特性允许多数据中心的Redis集群。Redis在大多数情况下是以主副本模式运行的。这适用于大量读取的缓存服务器。但这意味着,主节点是数据需要首先写入的地方,然后将这些数据分散到副本,以帮助平衡其缓存负载。有一个企业功能,允许对等的active-active集群。Redis可以自动分片和复制数据,但它的拓扑感知仅限于作为企业功能的机架感知。▶︎ ScyllaDBScyllaDB是按照Apache Cassandra中的分布式数据库模型设计的。因此,它默认是多数据中心集群。它可以自动分片,并且每个操作都有可调整的一致性,如果你想要更强的一致性,它甚至还支持轻量级事务来提供写入的线性化。就拓扑感知而言,ScyllaDB支持机架感知和数据中心意识,甚至支持标记感知和分片感知,不仅知道数据存储在哪个节点上,甚至可以知道与该数据关联的CPU。结论虽然对于什么是分布式数据库,还没有一个行业标准,但是我们可以看到,许多领先的SQL和NoSQL数据库,都在某种程度上支持一组核心功能或属性。其中有些功能是内置的,有些被认为是增值包或第三方选项。在本文分析的五个典型分布式数据库系统中,CockroachDB为SQL数据库提供了最全面的功能和特性,ScyllaDB为NoSQL系统提供了最全面的功能。该分析应被视为某个时间段的调查。鉴于下一个技术周期的需求,每一个数据库系统都在不断发展,这个行业并没有停滞不前。对用户来说,分布式数据库每年都在进步,变得更加灵活、性能更强、更具弹性和可扩展性。来源:今日头条
-
节点Citus 是一种 PostgreSQL 扩展,它允许数据库服务器(称为节点)在“无共享(shared nothing)”架构中相互协调。这些节点形成一个集群,允许 PostgreSQL 保存比单台计算机上更多的数据和使用更多的 CPU 内核。这种架构还允许通过简单地向集群添加更多节点来扩容数据库。扩展https://www.postgresql.org/docs/current/external-extensions.htmlCoordinator 与 Worker每个 cluster 都有一个称为 coordinator(协调器) 的特殊节点(其他节点称为 worker 节点)。应用程序将它们的查询发送到 coordinator 节点,coordinator 节点将其转发给相关的 worker 并累积结果。对于每个查询,coordinator 要么将其路由到单个 worker 节点,要么将其并行化到多个节点,具体取决于所需数据是位于单个节点上还是多个节点上。coordinator 通过查阅其元数据表知道如何做到这一点。这些 Citus 特定表跟踪 worker 节点的 DNS 名称和运行状况,以及跨节点数据的分布情况。分布式数据表类型Citus 集群中有三种类型的表,每种表都以不同方式存储在节点中,并且用于不同的目的。类型 1:分布式表第一种类型,也是最常见的,是分布式表。对于 SQL 语句而言,它们看似是普通的表,但在 worker 节点之间水平分区。这里 table 的行存储在 worker 的表 table_1001、table_1002 等中。组件 worker 表称为分片(shards)。分布列Citus 使用使用分片算法将行分配到分片。基于表列(称为分布列(distribution column))的值执行分配,此分配具有确定性。集群管理员在分布表时必须指定此列。做出正确的选择,这一点对于性能和功能有重要影响。类型 2:引用表引用表 是一种分布式表,其全部内容都集中到单个分片中,并在每个 worker 上复制。因此,对任何 worker 的查询都可以在本地访问 引用 信息,无需从另一个节点请求行,因此也不会产生此类网络开销。引用表没有分布列,因为无需区分每行的各个分片。引用表 通常很小,用于存储与在任何工作节点上运行的查询相关的数据。例如,订单状态或产品类别等枚举值。当与 引用表 交互时,我们会自动对事务执行两阶段提交 (2PC)。这意味着 Citus 确保您的数据始终处于一致状态,无论您是在写入、修改还是删除它。2PChttps://en.wikipedia.org/wiki/Two-phase_commit_protocol类型 3:本地表当您使用 Citus 时,您连接并与之交互的 coordinator 节点是安装了 Citus 扩展的常规 PostgreSQL 数据库。因此,您可以创建普通表并选择不对其进行分片。这对于不参与连接查询的小型管理表很有用。一个示例是用于应用程序登录和身份验证的用户表。创建标准 PostgreSQL 表很容易,因为它是默认值。这是你运行 CREATE TABLE 时得到的。在几乎每个 Citus 部署中,我们都会看到标准 PostgreSQL 表与 distributed 和 reference 表共存。事实上,如前所述,Citus 本身使用本地表来保存集群元数据。Shards上一节将分片描述为在 worker 节点内的较小表中包含分布式表的行的子集。本节详细介绍了技术细节。协调器上的 pg_dist_shard 元数据表包含系统中每个分布式表的每个分片的行。该行与分片 ID 相匹配,分片 ID 的范围是一组哈希整数 (shardminvalue, shardmaxvalue)。SELECT * from pg_dist_shard; logicalrelid | shardid | shardstorage | shardminvalue | shardmaxvalue ---------------+---------+--------------+---------------+--------------- github_events | 102026 | t | 268435456 | 402653183 github_events | 102027 | t | 402653184 | 536870911 github_events | 102028 | t | 536870912 | 671088639 github_events | 102029 | t | 671088640 | 805306367 (4 rows)如果 coordinator 节点要确定哪个分片包含 github_events 行,它将对行中分布列的值执行哈希算法。然后此节点检查哪个分片的范围包含此哈希值。定义范围后,哈希函数的image(图像)就是两者的并查。分片放置假设分片 102027 与相应的行关联。在某个 worker 中的 github_events_102027 表中读取或写入此行。是哪个 worker?这完全由元数据表确定。分片映射到 worker 的过程称为分片放置(shard placement)。coordinator 节点将查询重写为引用特定表(例如 github_events_102027)的片段,并对相应 worker 运行这些片段。下面的查询示例在后台运行,旨在查找分片 ID 为 102027 的节点。SELECT shardid, node.nodename, node.nodeport FROM pg_dist_placement placement JOIN pg_dist_node node ON placement.groupid = node.groupid AND node.noderole = 'primary'::noderole WHERE shardid = 102027; ┌─────────┬───────────┬──────────┐ │ shardid │ nodename │ nodeport │ ├─────────┼───────────┼──────────┤ │ 102027 │ localhost │ 5433 │ └─────────┴───────────┴──────────┘在 github_events 示例中,有四个分片。每个表的分片数量在其在集群中分布时是可配置的。最后请注意,Citus 允许复制分片以防止数据丢失。有两种复制“模式”:Citus 复制和流复制。前者创建额外的备份分片放置并针对所有更新它们的所有它们运行查询。后者效率更高,利用 PostgreSQL 的流式复制将每个节点的整个数据库备份到一个 follower 数据库。这是透明的,不需要 Citus 元数据表的参与。共置由于可以根据需要将分片及其副本放置在节点上,因此将包含相关表的相关行的分片放在同一节点上是有意义的。这样,它们之间的连接查询可以避免通过网络发送尽可能多的信息,并且可以在单个 Citus 节点内执行。一个示例是包含商店、产品和购买的数据库。如果所有三个表都包含 - 并且由 - store_id 列分布,那么限制在单个存储中的所有查询都可以在单个工作节点上高效运行。即使查询涉及这些表的任意组合也是如此。并行性跨多台机器分散查询允许一次运行更多查询,并允许通过向集群添加新机器来扩展处理速度。此外,如上一节所述,将单个查询拆分为片段可以提高专用于它的处理能力。后一种情况实现了最大的并行性,这意味着 CPU 内核的利用率。读取或影响均匀分布在多个节点上的分片的查询能够以“实时”速度运行。请注意,查询的结果仍然需要通过协调器节点传回,因此当最终结果紧凑时(例如计数和描述性统计等聚合函数),加速效果最为明显。查询执行在执行多分片查询时,Citus 必须平衡并行性的收益与数据库连接的开销(网络延迟和工作节点资源使用)。要配置 Citus 的查询执行以获得最佳的数据库工作负载结果,它有助于了解 Citus 如何管理和保存协调节点和工作节点之间的数据库连接。Citus 将每个传入的多分片查询会话转换为称为任务的每个分片查询。它将任务排队,并在能够获得与相关工作节点的连接时运行它们。对于分布式表 foo 和 bar 的查询,下面是连接管理图:coordinator 节点为每个会话都有一个连接池。每个查询(例如图中的 SELECT * FROM foo)仅限于为每个 worker 的任务打开最多 citus.max_adaptive_executor_pool_size(整数)个同时连接。该设置可在会话级别进行配置,以进行优先级管理。在同一连接上按顺序执行短任务比为它们并行建立新连接更快。另一方面,长时间运行的任务受益于更直接的并行性。为了平衡短任务和长任务的需求,Citus 使用 citus.executor_slow_start_interval(整数)。该设置指定多分片查询中任务的连接尝试之间的延迟。当查询首先对任务进行排队时,这些任务只能获取一个连接。在每个有待处理连接的时间间隔结束时,Citus 会增加它将打开的同时连接数。通过将 GUC 设置为 0,可以完全禁用慢启动行为。当任务完成使用连接时,会话池将保持连接打开以供以后使用。缓存连接避免了 coordinator 和 worker 之间重新建立连接的开销。但是,每个池一次打开的空闲连接不超过 citus.max_cached_conns_per_worker(整数)个,以限制 worker 中空闲连接资源的使用。最后,设置 citus.max_shared_pool_size (integer) 充当故障保险。它限制了所有任务之间每个 worker 的总连接数。
上滑加载中
推荐直播
-
华为云码道Agent集成与鸿蒙实战2026/08/11 周二 19:00-21:00
王一男-华为云码道产品规划专家;李炎-华为云码道产品专家;彭江敏-华为云鸿蒙端云一体化开发专家
本次直播带你解读华为云码道7月份产品新特性、新功能。更有专家演示码道Agent Space × 钉钉机器集成实战,从0到1打通消息通道;码道鸿蒙端云一体化实战,快速搭建员工签到系统。
回顾中 -
华为云开发者AI素养直播课·第五期2026/09/04 周五 16:00-18:00
林华鼎-华为云AI开发者运营负责人;蒋春阳-华为云AI开发者案例开发专家
本期直播内容: AI工具体验营 · 第5-8课连讲。Agent-Team 多智能体协作完成毕业设计实践
回顾中 -
华为云开发者AI素养ClassRoom·第六期2026/09/08 周二 19:00-20:00
樊渊-2026华为软件挑战赛冠军
高手来了:看软挑高手解析二维排样问题—从工业难题到算法突破
回顾中
热门标签