• 蚂蚁上市被叫停!蚂蚁的程序员们怎么样了?

                        继马云被有关部门联合约谈以后,万众瞩目的蚂蚁上市被叫停了! 一石激起千层浪,这个爆炸性的新闻引起了人们的热议,来看看大家都说了些什么。 首先表达一下对蚂蚁金服员工的深切同情,毕竟之前大家都以为马上就能实现财务自由,走上人生巅峰,结果来了这么一出,真是世事无常。 网友们纷纷猜测蚂蚁的兄弟们是不是已经哭晕在厕所了,当初说人均买得起280平的豪宅,现在全成了泡沫。有人猜测蚂蚁员工此时正疯狂给售楼处打电话,要求把280平的豪宅换成28平的动迁房…… 还有人说,蚂蚁的办公室又欢呼了,上次是高p们欢呼财务自由,这次是p5p6们欢呼,谁让你们不带我们玩?这下大家都没得玩了吧?p7p8们估计都急哭了。 大家心里肯定想,之前的班白加了,996的心情都没了。 不过心情差的不只是蚂蚁员工,还有杭州房产中介和房东们,毕竟蚂蚁上市还和当地房价息息相关,谁也别好过了。 阿里员工爆料,今天楼道里抽烟的人都变多了。唉,股价暴跌,心疼那些刚打完新股的朋友们,抽支烟解解愁吧。 还有网友问,这是688688要变成886886的节奏吗?之前的股票代码是668,多么吉利的数字,转眼就成了“拜拜喽”。 网友说,这也是一种福报。马老板不是总说996是福报吗?这次修到自己头上来了。阿里不是喜欢pua吗?这次pua到监管部门头上去了,闹大了吧? 之前马老板还让大家“拥抱变化”,如今他遭此变故,那就好好拥抱吧。网友猜测,没准这是马老板为了鼓励大家继续修福报出的主意,可谓用心良苦。 还有人恭喜蚂蚁再创第一,成为第一家认购结束被暂缓上市的公司。这个“第一”,估计谁都不想当…… 有才的网友写了一幅对联,上联:说你行你就得行,不行也行!下联:说你不行就不行,行也不行!横批:马已今服(蚂蚁金服)。 小编不禁想起微博流传的一句话:你们都跟马云叫爸爸,这下知道爷爷是谁了吧? 一切商业行为都要戴着镣铐跳舞,不能逾越雷池,更不能让亿万用户承担巨大风险。 人说蚂蚁拿银行的钱去高利贷给普通民众,凭借垄断挣黑心钱,根本不是什么高科技公司,不惩不足以警示后来者。 一旦出事,全国小微企业都得跟着一起遭殃,那就不是单纯约谈的问题了。 不过也有人说,这么说话就不地道了。第一借款利率明码标价,没有p2p的套路;第二,借款自愿;第三,既然要享受借款,又不想提供任何抵押,利率高点就不应该不乐意。放贷企业也承担着你跑路的风险,怎么能又享受借款便利,又不愿意承受高利率,哪有这种好事? 公司行为造成的后果最终都会落到员工头上,有个蚂蚁员工战战兢兢地问出了大家的心声:原来说好的一千万股票是不是会缩水到60万? 网友回答,准确地说应该缩水到66万。 因为蚂蚁可能会被重新估值,原来作为科技企业估值比较高,但如果按照金融企业估值的话,估计身价会直接缩水15倍。 蚂蚁员工们绝对想不到,睡一觉起来,资产缩水了这么多,真是恍如一场大梦。 最后,让我们把时间倒回六天前,那时一个蚂蚁金服的程序员还兴致勃勃地发帖说自己今年升p7,又得知交往一年半的女朋友是个富二代。 下面一片羡慕声,蚂蚁要上市,楼主升p7,女友富二代,好事成三,楼主简直是人生赢家! 真想知道这位同学现在的心情,希望他的富二代女友能多发几个红包安慰安慰他吧。 不过才短短几天时间,许多人从巅峰掉了下来,虽然不至于落到谷底,也是一次不小的打击。毕竟从来没得到过和得到过又失去完全不一样,那种落差和失望大概需要消化一阵子了。 不可否认马云是个杰出的企业家,阿里是家伟大的公司,蚂蚁也为大家的生活提供了许多方便。我们鼓励创新,鼓励开拓,但所有的创造和改变都要建立在合理合法合规的基础上。 国家发展,以稳为根,这种巨型企业的一举一动都事关无数人的钱袋子,资本虽然无形,却有移山倒海的力量,不能小觑,更不能轻率。 长按订阅更多精彩▼ 如有收获,点个在看,诚挚感谢

                        时间:2020-11-09 关键词: 程序员 金融科技

                      • 如何构建一个好的电商搜索引擎?

                        ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 分享嘉宾:邢少敏?第四范式 架构师 编辑整理:刘员京 出品平台:DataFunTalk ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 导读: 机器学习算法的不断进步,搜索引擎巧妙的人机交互设计,分布式系统的革新让搜索引擎在不知不觉中成为人们生活中不可或缺的一部分。同时,随着人们新需求的不断涌现,搜索引擎也没有停下变革的步伐。本文主要分享智能搜索在电商的应用探索,介绍如何构建一个好的电商搜索引擎。主要内容包括: 为什么要做搜索 整体的技术方案 实际应用效果 01 电商搜索需求背景 首先,给大家分享下为什么要做搜索。 1. 被忽视、低估的搜索行为 在电商的app里,流量来自很多不同的渠道,比如说搜索、推荐、活动和直播等等。搜索,是电商app非常重要的一个流量入口,可能很多电商app来自搜索的流量都会占过半以上。对于需求明确的用户主要还是通过搜索来触达,对于需求不明确的用户主要通过推荐。那么,对于搜索,因为需求比较明确,所以会更容易转化。 2.?搜索用户体验痛点 一些电商巨头其实已经把搜索体验做得非常好,但是一些体量较小的客户依然做不好搜索体验,所以这就给我们提供了市场机会。 3. 搜索痛点下的用户流失 如果搜索做得不好,用户搜索多次,浏览搜索结果超过一定时间或者翻页几次以后,都找不到结果,就会因为无法忍受搜索体验而流失。 4. 智能搜索挖掘用户行为数据价值 所以应该优化搜索体验,留住用户,那应该如果做好智能搜索呢?可以通过用户行为日志挖掘到很多有价值的数据,从这些数据中找到丰富的特征,利用这些特征去将搜索流量的价值最大化。 5. 电商搜索举例 一般情况下,对于搜索,除了我们经常看到的去搜索框里面敲一些关键词来搜索以外,搜索还有其他场景,比如搜索发现、搜索建议、热门搜索、猜你喜欢和搜索底纹,其实这些已经不是单纯的搜索,而是跟推荐相结合的场景。 6. 商品搜索?VS. 网页搜索 日常生活中,最熟悉的网页搜索和商品搜索有什么区别?可以从这几个方面来分析: 商品搜索和网页搜索的优化目标不一样,网页搜索主要是优化网页和搜索词的相关性 ( 不考虑网页搜索中的广告点击率优化 );而商品搜索主要优化目标是点击率 ( CTR )、转化率 ( CVR )、交易额 ( GMV ),两者的优化目标是有一些不同的。 从数据结构方面来讲,网页搜索使用的是全网的非结构化数据,需要额外的非结构化数据处理工作;而对于商品搜索,使用的是优质的结构化数据,比起网页搜索里面参差不齐的非结构化数据,少了数据整理和处理的工作。 从数据来源方面来讲,网页搜索使用的是整个互联网的数据,而商品搜索,往往是一家企业内部的数据,而且这些数据存储在它的业务数据库或者数仓里,相对来说数据是比较好处理的。 从数据规模来讲,网页搜索使用的数据一般是万亿级的规模,有超过万亿的网页,但是商品搜索的话,根据客户规模的大小,商品的SKU数或者SPU数基本上是几万到几千万这个级别,与网页搜索不在一个量级。 从召回率来讲,网页搜索对召回率的要求不会太高,但是商品搜索对召回率的要求是很高的,因为不能让一些商品永远没有曝光的机会,所以一定是需要让所有的商品都有曝光的机会,商品搜索对于召回率的要求是很高的。 从个性化程度来讲,网页搜索一般情况下也能做到个性化,通常像谷歌、百度等搜索公司在个性化上也会做一些工作,但是对个性化的要求并不高;而商品搜索对个性化的要求很高,比如搜索的时候,不同的人消费能力的不同,那么排序的时候,需要考虑把合适价格的产品返回给不同消费能力的人群。个性化要求的不同是网页搜索和商品搜索的重要区别,这就决定了两者技术实现的不同。 02 技术方案探索 接下来,介绍一下总体的技术方案。 技术架构图主要分为三大块,一块是数据,一块是模型,一块是搜索引擎本身,其中数据和模型是为搜索引擎服务的,会有数据接入的一些模块,把客户的数据接入到系统里面,放入数据中台上去计算物料画像、用户画像等等;接下来,需要用这些数据建一些模型,这些模型会在搜索引擎的各个环节中用到,比如意图、召回、粗排、精排中各个环节都会用到;再往下,就是一些基础的数据存储中间件。我们主要围绕着搜索引擎本身这个流程展开,最右侧就是搜索引擎的流程,接下来我们从上往下来介绍一下整个搜索是如何做的。 1. Query预处理 当用户在一个电商app上输入搜索词的时候,会先对搜索词进行预处理,这种预处理就包括常见的去停止词、归一化、拼音转文字、同义词替换、分词、补全、改写和纠错等等一系列的处理,然后把用户搜索的不太规范或者不正确的query处理成规范形式和正确形式,并且做一些分词、转换的处理。 2. 实体识别 做完预处理之后,得到了用户搜索词分词的结果,拿到这个分词结果,要把分词结果里面每一个词识别成一个实体,什么是实体呢?在电商里面的实体类型其实有很多,这里列出了三种,有商品实体类型,矿泉水就是一种实体,属于商品实体类型;农夫山泉是品牌这种实体类型;饮用水是一种分类或者叫类目,这些都是实体类型,实体类型下面有具体的实体,实体就是矿泉水,农夫山泉,所以需要知道输入的词到底是一个什么实体,比如说输入“奥利奥饼干”,做完预处理之后,得到“奥利奥”和“饼干”两个词,这个时候就需要做实体识别,识别后可以知道“奥利奥”是一种品牌,“饼干”是一种商品,这样就能做后续的处理。 实体识别是序列标注的一种,有很多种方法,像CRF、BERT之类的,都可以用来做实体识别,在工程上处理的时候不一定是在线使用这些算法,因为这些算法在线计算成本比较高,通常会进行离线计算,把计算出的结果放到缓存中,这样在线只需要做一些简单的匹配,处理会快很多,另外有时候还需要经过一些人工纠正,这样才能得到比较准确的实体词。做实体识别有一些前提条件,怎么知道矿泉水是一种商品?农夫山泉是一种品牌呢?这些知识其实是需要外部输入才能知道,这就是领域知识,所以首先要积累一些领域知识。 ① 领域知识积累 领域知识其实是不太好分析出来的,举个例子,猪舌和口条其实是一回事,茭瓜和西葫芦是一回事,这些知识,当然可以去分析,那如何分析?其实有很多现成的知识可以抓取过来利用,把它作为领域知识积累下来。这个领域知识有很多形态,最简单就是词库,也可以构建知识图谱,构建知识图谱是构建领域知识最常用的方式。 ② 词库挖掘 词库如何构建,需要挖掘各种类型的词,比如最常用的同义词和上位词,同义词理解可以用前面举的例子,茭瓜和西葫芦是一回事,获取同义词有很多种方法,使用预训练的词向量方法去找共现关系可以大量的找到同义词 ( 也就是类似word2vec的方法 ),但是找出来之后可能不太准确,需要后期处理一下才能使用。从百度百科上可以爬取到很多同义词,以及业务运营数据库和企业现有词库积累都可以找到同义词,有各种各样的方法去构建同义词库。 那么如何挖掘上位词,举例理解上位词,比如商品类目就是具体商品的上位词,矿泉水的上位词就是饮用水。词库的构建是做搜索必要的工作,但是在构建词库的过程中,不一定是手工的过程,完全可以用其他的自动化方法甚至模型去筛选词库,最后再做一些人工纠正。 ③ 商品知识图谱构建 如何构建商品知识图谱,我们可以构建很多种不同类型的知识图谱,本文是根据不同实体来构建知识图谱,比如按照三种实体类型来构建知识图谱,像上图最右侧的示意图,苹果有很多种型号,如果用户搜索苹果,用户有可能想买iPhone 11、iPhone X或者还是没出来的iPhone 12,可以通过先验知识,把知识图谱构建出来,最后排序时可以把这些知识融入进去,比如用户都更加倾向于去买iPhone X,后面排序的时候iPhone X就会更靠前一些。对于类目来说,搜索苹果有可能是一个手机,也有可能是水果,那到底是想买手机还是想吃水果,是有一个概率的,不同用户有不同的倾向性,但是目前我们构建的图谱还不能做到特别个性化,它只是一个宏观的统计,搜苹果时有80%的用户其实是要买苹果手机的,有20%的用户要买水果,这样就给了我们一种排序的参考。知识图谱其实是做了一个非个性化全局的知识构建,通过商品库去分析静态概率,最后根据用户点击行为会做一些动态调整,调整完的知识图谱再用在后面的排序上。 3. 意图识别 将用户搜索词做了预处理之后,基于分词结果识别搜索词对应的实体类型,可以知道用户搜一个商品的时候,搜的是什么样的实体,是一个品牌,还是一个商品名称,还可以通过图谱去猜测用户的搜索意图,如果他只输一个苹果,能猜出来很大概率上可能要买手机,也可以把其他实体类型也猜出来,猜完了以后,还是有一部分猜不出来,那猜不出来的这部分怎么办呢,就要用意图识别。 那么如何做意图识别,使用用户导入的物料库自动的去训练意图模型,意图识别就是去做类目预测,甚至去做一些字面没有表达出来的其他实体类型的预测。在初始的物料库里面,商品的各种属性就是一些天然的标注数据,使用这些标注数据去训练一个初始的意图模型,来预测隐含的实体类型,当这个初始模型训练完成之后,再用搜索日志去动态调整这个意图模型。 做完预处理、分词、实体识别、基于知识图谱的预测和意图识别,能做到什么效果呢?能做到搜"手机",根据这个用户的信息,就可以知道手机是一个商品名字,还可以猜出来具体商品,但是猜的可能不一定那么准,这个用户可能有80%的概率要买苹果手机,而且他买的这个苹果手机可能是iPhone 11,还可能猜出来要买的颜色是红色的。这样在用户输入一个词的时候,就能预测出他可能要搜的所有的信息,当然这个预测有时准有时不准,但后面会调整,这样的话,就可以拿着这些信息去做一些召回。 意图识别有哪些方法,意图识别的方法有很多种,因为意图识别本身用的就是分类器,分类器其实有好多种,但是经过各种对比之后,我们选择了能在线上使用的FastText,同等效果下,FastText是最快的,并且简单高效,实用性高。 4. 粗排 做完前面的工作就开始做召回,从用户搜索的一个词通过一系列流程,通过知识图谱 ( 其实知识图谱放的是一些比较头部的实体,但是长尾的实体词还是需要意图识别的方法来预测 ) 预测出了各种信息,拿着这些信息去构建召回的条件,用这个召回的条件去召回出来完整的结果集合,这个时候召回的工作就完成了。 召回的工作完成之后,接下来就是粗排,可以使用简单的模型来粗排,这个模型里面的特征可以用相关性 ( 搜索和推荐不同,搜索一开始就会有相关性,但推荐就不会有相关性,推荐不会先输入一些搜索词 )、时间、热度、销量、好评数和收藏数等等特征,训练出简单的模型,做一些粗排的排序,进行截断,进入下一个环节,想要更简单的话,可以找出核心的特征,做加权平均也可以。粗排还不能达到个性化的效果,当然也可以把粗排做得更个性化,可以根据不同搜索的用户做个性化的粗排模型。 5. 精排 得到粗排结果以后,接下来就是精排,对于搜索来讲,目前来讲主要的优化目标是CTR,用的主要是CTR预估方法,CTR预估有很多不同的方法,比如传统的特征工程方法、深度学习方法等,也可以使用第四范式自研的HyperCycle。 特征工程方法主要是利用不同种类的多种特征,构建机器学习排序模型,上面列了几组特征,有搜索词特征、相关性特征、用户特征、商品特征和行为特征等。 深度学习方法也是常用的CTR预估方法,有很多深度学习模型可以用于搜索场景的排序,比如DeepFM、Wide&Deep等。 我们系统中主要使用的是自研的HyperCycle。简单来说会自动蓄水积累数据、自动探索模型、自动挖掘特征,自动训练上线,还会定期自动更新,详细信息可以参考后面石光川分享的HyperCycle。 6. 其他 搜索中会出现推荐相关的应用场景,像搜索底纹、搜索发现、搜索提示、猜你喜欢和相关搜索等等都和推荐相关。 搜索底纹就是搜索框里面唯一的那个词,其实就是对搜索框top1的推荐,根据用户的历史行为,推荐出该用户最有可能搜的词汇取top1放在搜索底纹里,然后推荐给用户,用户看见这个底纹以后就有可能去搜这个底纹上的搜索词,目的是希望引导用户,猜出用户想要搜什么,提高转化率;搜索发现跟搜索底纹的原理差不多,只是有了更多推荐的搜索词;搜索提示是在搜索中做一些推荐,相关搜索是在没有搜索结果时做一些相关推荐;有的地方还会有猜你喜欢,猜你喜欢其实是一个纯推荐的场景,当用户打开搜索页面时,去猜用户最想要搜索的是什么,然后推荐给用户。这些其实都是搜索中的推荐,搜索中的流量和推荐中的流量是完全可以打通的。 以上,逐个讲了整个搜索的流程,那么现在分步的去看搜索一个词时是怎样的过程。第一步会先输入搜索词"康师傅方便面",第二步预处理,预处理会做一些事情,首先是分词,之后会算出来该搜索词可能的实体类型,比如康师傅是一个品牌,它识别出康师傅是一个品牌,方便面可能是一种修饰语,也可能是一种类型,还有一些同义词:袋装面、桶装面和泡面,做完第二步的处理,会拿到这样一些处理结果;第三步意图识别,可以看到有96%的概率所属类目是粮油调味; 第四步构建一个搜索query,从ES召回结果;第五步拿到ES召回的结果之后,做粗排并截断;第六步做精排;最后做基于业务规则的运营干预,把最终的搜索结果返回给用户,以上就是完整的技术流程。 03 应用案例和效果 最后,我们看看搜索技术方案应用案例,分析产生的效果。 在一些零售企业场景应用之后搜索结果准确率提升了50%,整个商品的覆盖率提高了3倍,解决了客户的搜索体验痛点。 这是上线前后搜索结果的对比,没上线前搜索"苹果"时,排在前面并不是苹果,上线智能搜索之后,搜索结果都是"苹果"相关的。 按品类搜索,优化前搜索"水",Top 5返回了"丰水梨"、"柔肤水"等完全不相关产品,优化后搜索"水",Top 5返回是和水紧密相关商品。 按品牌搜索,优化前搜索"安慕希",Top 5返回了"希艺欧"完全不相关商品,优化后搜索"安慕希",Top 5返回是和品牌紧密相关商品。 按同义词搜索,优化前搜索"圣女果",Top5返回了"果汁饮料"、"芒果味果冻"毫不相关的商品,优化后搜索"圣女果",Top5返回是和圣女果紧密相关商品。 优化后,可以进行智能纠错和拼音搜索,比如搜索 "平果"、"pingguo" 和 "pinguo" 时,都能准确搜索出苹果相关的商品。 嘉宾介绍: 邢少敏,17年加入第四范式,一直在做业务产品的研发,最初做智能客服系列产品,去年孵化了智能搜索产品,今年同时在做智能推荐产品的研发。 今天的分享就到这里,谢谢大家。 特别推荐一个分享架构+算法的优质内容,还没关注的小伙伴,可以长按关注一下: 长按订阅更多精彩▼如有收获,点个在看,诚挚感谢 免责声明:本文内容由21ic获得授权后发布,版权归原作者所有,本平台仅提供信息存储服务。文章仅代表作者个人观点,不代表本平台立场,如有问题,请联系我们,谢谢!

                        时间:2020-11-09 关键词: 互联网 电子商务 搜索引擎

                      • 【性能优化】纳尼?内存又溢出了?是时候总结一波了!

                        案例介绍 这里,我将在平时工作过程中总结的内存溢出的情况,以代码案例的形式直观的分享给大家,希望能够为小伙伴们带来实质性的帮助。 接下来,我们就以代码案例的形式来分析各种内存溢出的情况。 定义主类结构 首先,我们创建一个类叫做BlowUpJVM,所有的案例实验都是基于这个类进行。 public?class?BlowUpJVM?{??}? 栈深度溢出 public?static?void??testStackOverFlow(){???????BlowUpJVM.testStackOverFlow();?}? 栈不断递归,而且没有处理,所以虚拟机栈就不断深入不断深入,栈深度就这样溢出了。 永久代内存溢出 public?static?void?testPergemOutOfMemory1(){????//方法一失败?????List?list?=?new?ArrayList();?????while(true){???????list.add(UUID.randomUUID().toString().intern());????}?}? 打算把String常量池堆满,没想到失败了,JDK1.7后常量池放到了堆里,也能进行垃圾回收了。 然后换种方式,使用cglib,用Class把老年代取堆满 public?static?void?testPergemOutOfMemory2(){????try?{???????while?(true)?{??????????Enhancer?enhancer?=?new?Enhancer();??????????enhancer.setSuperclass(OOM.class);??????????enhancer.setUseCache(false);??????????enhancer.setCallback(new?MethodInterceptor()?{?????????????@Override?????????????public?Object?intercept(Object?obj,?Method?method,?Object[]?args,?MethodProxy?proxy)?throws?Throwable?{????????????????return?proxy.invokeSuper(obj,?args);?????????????}??????????});??????????enhancer.create();???????}????}????catch?(Exception?e){???????e.printStackTrace();????}?}? 虚拟机成功内存溢出了,那JDK动态代理产生的类能不能溢出呢? public?static?void?testPergemOutOfMemory3(){????while(true){????final?OOM?oom?=?new?OOM();????Proxy.newProxyInstance(oom.getClass().getClassLoader(),?oom.getClass().getInterfaces(),?new?InvocationHandler()?{??????????public?Object?invoke(Object?proxy,?Method?method,?Object[]?args)?throws?Throwable?{?????????????Object?result?=?method.invoke(oom,?args);?????????????return?result;??????????}???????});????}?}? 事实表明,JDK动态代理差生的类不会造成内存溢出,原因是:JDK动态代理产生的类信息,不会放到永久代中,而是放在堆中。 本地方法栈溢出 public?static?void?testNativeMethodOutOfMemory(){????int?j?=?0;????while(true){???????Printer.println(j++);???????ExecutorService?executors?=?Executors.newFixedThreadPool(50);???????int?i=0;???????while(i++

                        时间:2020-11-09 关键词: 嵌入式 代码

                      • 浅谈大数据中的2PC、3PC、Paxos、Raft、ZAB

                        一致性 简述 一致性,是指对每个节点一个数据的更新,整个集群都知道更新,并且是一致的。假设一个具有N个节点的分布式系统,当其满足以下条件时,我们说这个系统满足一致性: 全认同: 所有N个节点都认同一个结果 值合法: 该结果必须由N个节点中的过半节点提出 可结束: 决议过程在一定时间内结束,不会无休止地进行下去 面临着的问题 消息传递异步无序: 现实网络不是一个可靠的信道,存在消息延时、丢失,节点间消息传递做不到同步有序 节点宕机: 节点持续宕机,不会恢复 节点宕机恢复: 节点宕机一段时间后恢复,在分布式系统中最常见 网络分化: 网络链路出现问题,将N个节点隔离成多个部分 拜占庭将军问题: 节点或宕机或逻辑失败,甚至不按套路出牌抛出干扰决议的信息 如下形象demo: 周五我:晚上下班吃鸡周六凌晨xc:好的?????????????????????????????//?消息延迟我:WC---------------------------------我:晚上下班吃鸡xc:No(两小时后)xc:No problem!?????????????????????//?宕机节点恢复我:WC---------------------------------我:晚上下班吃鸡...?????????????????????????????????//?节点宕机---------------------------------我:晚上下班吃鸡cx:好,我们去大保健!?????????????????//?拜占庭将军我:WC 前面 已经讨论过,在分布式环境下,有很多不确定性因素,故障随时都回发生,也讲了CAP理论,BASE理论。我们希望达到在分布式环境下能搭建一个高可用的,且数据高一致性的服务,目标是这样,但CAP理论告诉我们要达到这样的理想环境是不可能的。这三者最多完全满足2个。 在这个前提下,P(分区容错性)是必然要满足的,因为毕竟是分布式,不能把所有的应用全放到一个服务器里面,这样服务器是吃不消的,而且也存在单点故障问题。所以,只能从一致性和可用性中找平衡。 怎么个平衡法?在这种环境下出现了BASE理论:即使无法做到强一致性,但分布式系统可以根据自己的业务特点,采用适当的方式来使系统达到最终的一致性;BASE由Basically Avaliable 基本可用、Soft state 软状态、Eventually consistent 最终一致性组成,一句话概括就是:平时系统要求是基本可用,除开成功失败,运行有可容忍的延迟状态,但是,无论如何经过一段时间的延迟后系统最终必须达成数据是一致的。 其实可能发现不管是CAP理论,还是BASE理论,他们都是理论,这些理论是需要算法来实现的,今天讲的2PC、3PC、Paxos算法,ZAB算法就是干这事情。 所以今天要讲的这些的前提一定是分布式,解决的问题全部都是在分布式环境下,怎么让系统尽可能的高可用,而且数据能最终能达到一致。 2PC 2PC(tow phase commit)两阶段提交。它本身是一致强一致性算法,所谓的两个阶段是指:第一阶段:准备阶段(投票阶段) 第二阶段:提交阶段(执行阶段)。我们将提议的节点称为协调者(coordinator),其他参与决议节点称为参与者(participants, 或cohorts)。 阶段1 在阶段1中,协调者发起一个提议,分别问询各参与者是否接受,如下图: 在这里插入图片描述 阶段2 在阶段2中,协调者根据参与者的反馈,提交或中止事务,如果参与者全部同意则提交,只要有一个参与者不同意就中止。如下图: 在这里插入图片描述 实例 下面我们通过一个例子来说明两阶段提交协议的工作过程:A组织B、C和D三个人去爬山:如果所有人都同意去爬山,那么活动将举行;如果有一人不同意去爬山,那么活动将取消。用 2PC 算法解决该问题的过程如下: 首先A将成为该活动的协调者,B、C和D将成为该活动的参与者。 阶段1: A发邮件给B、C和D,提出下周三去爬山,问是否同意。那么此时A需要 等待B、C和D的邮件。 B、C和D分别查看自己的日程安排表。B、C发现自己在当日没有活动安排,则发邮件告诉A它们同意下周三去爬山。由于某种原因, D白天没有查看邮 件。那么此时A、B和C均 需要等待。到晚上的时候,D发现了A的邮件,然后查看日程安排,发现周三当天已经有别的安排,那么D回复A说活动取消吧。 阶段2: 此时A收到了所有活动参与者的邮件,并且A发现D下周三不能去爬山。那么A将发邮件通知B、C和D,下周三爬山活动取消。 此时B、C回复A太可惜了,D回复A不好意思。至此该事务终止。 数据库中的2PC 在innodb存储引擎,对数据库的修改都会写到undo和redo中,不只是数据库,很多需要事务支持的都会用到这个思路。 对一条数据的修改操作首先写undo日志,记录的数据原来的样子,接下来执行事务修改操作,把数据写到redo日志里面,万一捅娄子,事务失败了,可从undo里面回复数据。 不只是数据库,在很多企业里面,比如华为等提交数据库修改都回要求这样,你要新增一个字段,首先要把修改数据库的字段SQL提交给DBA(redo),这不够,还需要把删除你提交字段,把数据还原成你修改之前的语句也一并提交者叫(undo) 数据库通过undo与redo能保证数据的强一致性,要解决分布式事务的前提就是当个节点是支持事务的。 这在个前提下,2pc借鉴这失效,首先把整个分布式事务分两节点,首先第一阶段叫准备节点,事务的请求都发送给一个个的资源,这里的资源可以是数据库,也可以是其他支持事务的框架,他们会分别执行自己的事务,写日志到undo与redo,但是不提交事务。 当事务管理器收到了所以资源的反馈,事务都执行没报错后,事务管理器再发送commit指令让资源把事务提交,一旦发现任何一个资源在准备阶段没有执行成功,事务管理器会发送rollback,让所有的资源都回滚。这就是2pc,非常非常简单。 说他是强一致性的是他需要保证任何一个资源都成功,整个分布式事务才成功。 在这里插入图片描述 优缺点 在异步环境并且没有节点宕机的模型下,2PC可以满足全认同、值合法、可结束,是解决一致性问题的一种协议。从协调者接收到一次事务请求、发起提议到事务完成,经过2PC协议后增加了2次RTT(propose+commit),带来的时延增加相对较少。优点: 优点:原理简单,实现方便 缺点: 缺点:同步阻塞,单点问题,数据不一致,容错性不好 同步阻塞 在二阶段提交的过程中,所有的节点都在等待其他节点的响应,无法进行其他操作。这种同步阻塞极大的限制了分布式系统的性能。 单点问题 协调者在整个二阶段提交过程中很重要,如果协调者在提交阶段出现问题,那么整个流程将无法运转。更重要的是,其他参与者将会处于一直锁定事务资源的状态中,而无法继续完成事务操作。 数据不一致 假设当协调者向所有的参与者发送commit请求之后,发生了局部网络异常,或者是协调者在尚未发送完所有 commit请求之前自身发生了崩溃,导致最终只有部分参与者收到了commit请求。这将导致严重的数据不一致问题。 容错性不好 二阶段提交协议没有设计较为完善的容错机制,任意一个节点是失败都会导致整个事务的失败。 3PC 三阶段提交(Three-phase commit),是二阶段提交(2PC)的改进版本。与两阶段提交不同的是,三阶段提交有两个改动点。 引入超时机制。同时在协调者和参与者中都引入超时机制。 在第一阶段和第二阶段中插入一个 准备阶段。保证了在最后提交阶段之前各参与节点的状态是一致的。也就是说,除了引入超时机制之外,3PC把2PC的 准备阶段再次一分为二,这样三阶段提交就有CanCommit、PreCommit、DoCommit三个阶段。 在这里插入图片描述 第一阶段canCommit 3PC的CanCommit阶段其实和2PC的准备阶段很像。协调者向参与者发送commit请求,参与者如果可以提交就返回Yes响应,否则返回No响应。 1.事务询问 协调者向参与者发送CanCommit请求。询问是否可以执行事务提交操作。然后开始等待参与者的响应。2. 响应反馈 参与者接到CanCommit请求之后,正常情况下,如果其自身认为可以顺利执行事务,则返回Yes响应,并进入预备状态。否则反馈No 第二阶段PreCommit 协调者根据参与者的反应情况来决定是否可以记性事务的PreCommit操作。根据响应情况,有以下两种可能。假如协调者从所有的参与者获得的反馈都是Yes响应,那么就会执行事务的预执行。 发送预提交请求 协调者向参与者发送PreCommit请求,并进入Prepared阶段。 事务预提交 参与者接收到PreCommit请求后,会执行事务操作,并将undo和redo信息记录到事务日志中。 响应反馈 如果参与者成功的执行了事务操作,则返回ACK响应,同时开始等待最终指令。 假如有任何一个参与者向协调者发送了No响应,或者等待超时之后,协调者都没有接到参与者的响应,那么就执行事务的中断。 发送中断请求 协调者向所有参与者发送abort请求。中断事务 参与者收到来自协调者的abort请求之后(或超时之后,仍未收到协调者的请求),执行事务的中断。 第三阶段doCommit 该阶段进行真正的事务提交,也可以分为以下两种情况。 执行提交 发送提交请求 协调接收到参与者发送的ACK响应,那么他将从预提交状态进入到提交状态。并向所有参与者发送doCommit请求。 事务提交 参与者接收到doCommit请求之后,执行正式的事务提交。并在完成事务提交之后释放所有事务资源。 响应反馈 事务提交完之后,向协调者发送Ack响应。 完成事务 协调者接收到所有参与者的ack响应之后,完成事务。 中断事务协调者没有接收到参与者发送的ACK响应(可能是接受者发送的不是ACK响应,也可能响应超时),那么就会执行中断事务。 发送中断请求 协调者向所有参与者发送abort请求 事务回滚 参与者接收到abort请求之后,利用其在阶段二记录的undo信息来执行事务的回滚操作,并在完成回滚之后释放所有的事务资源。 反馈结果 参与者完成事务回滚之后,向协调者发送ACK消息 中断事务 协调者接收到参与者反馈的ACK消息之后,执行事务的中断。 所有数据库的分布式事务一般都是二阶段提交,而这三阶段的思想更多的被借鉴扩散成其他的算法。 优缺点 与2PC区别: 第二阶段才写undo和redo事务日志 第三阶段协调者出现异常或网络超时参与者也会commit 优点: 改善同步阻塞 改善单点故障 缺点: 同步阻塞 单点故障 数据不一致 容错机制不完善 Paxos算法 这算法的提出者莱斯利·兰伯特在前面几篇论文中都不是以严谨的数学公式进行的。其实这个paxos算法也分成两阶段。首先这个图有2个角色,提议者与接收者。 第一阶段 提议者对接收者吼了一嗓子,我有个事情要告诉你们,当然这里接受者不只一个(一半要奇数个),它也是个分布式集相当于星期一开早会,可耻的领导吼了句:“要开会了啊,我要公布一个编号为001的提案,收到请回复”。这个时候领导就会等着,等员工回复1“好的”,如果回复的数目超过一半,就会进行下一步。如果由于某些原因(接收者死机,网络问题,本身业务问题),导致通过的协议未超过一半, 这个时候的领导又会再吼一嗓子,当然气势没那凶残:“好了,怕了你们了,我要公布一个新的编号为002的提案,收到请回复1”【其实和上学时候老师讲课很像,老师经常问听懂了吗?听懂的回1,没懂的回2,只有回复1的占了大多数,才能讲下个知识点】 第二阶段 接下来到第二阶段,领导苦口婆心的把你们叫来开会了,今天编号002提案的内容是:“由于项目紧张,今天加班到12点,同意的请举手”这个时候如果绝大多少的接收者都同意,那么好,议案就这么决定了,如果员工反对或者直接夺门而去,那么领导又只能从第一个阶段开始:“大哥,大姐们,我有个新的提案003,快回会议室吧。。” paxos的核心就是少数服从多数。 苦逼的领导(单点问题):有这一帮凶残的下属,这领导要不可能被气死,要不也会辞职,这是单点问题。凶神恶煞的下属(一致性问题):如果员工一直都拒绝,故意和领导抬杆,最终要产生一个一致性的解决方案是不可能的。 所以paxos协议肯定不会只有一个提议者,作为下属的员工也不会那么强势 协议要求:如果接收者没有收到过提案编号,他必须接受第一个提案编号 如果接收者没有收到过其他协议,他必须接受第一个协议。一旦一个提议被大家同意,那么之后的人再次提议,也是无效的,结果必须跟先前被大家接受的一致。 形象解说 Paxos算法解决的问题是在一个可能发生消息延迟、丢失、重复的分布式系统中如何就某个值达成一致,保证不论发生以上任何异常,都不会破坏决议的一致性。这 个“值”可能是一个数据的某,也可能是一条LOG等;根据不同的应用环境这个“值”也不同。 一个典型的场景是,在一个分布式数据库系统中,如果各节点的初始状态一致,每个节点都执行相同的操作序列,那么他们最后能得到一个一致的状态。为保证每个节点执行相同的命令序列,需要在每一条指令上执行一个一致性算法以保证每个节点看到的指令一致。 例如:公司商定年会举办的地点,每个人都可以提出建议。在现实环境中我们可以在一个会议室共同讨论或在微信群中讨论(基于内存共享方式);但在基于消息传递的分布式环境中每个人只能通过手机短信与其它人通过。如何在这种会延迟、丢失的环境中确定一个年会举办地点; Paxos算法是这样解决这个问题: 1、每个人都可以提出建议、同意建议、接受建议 2、少数服从多数。只要建议被多数人同意即可确定该建议。于是确定以下讨论方式:1、只有被提出来的建议才能被大家同意。2、最终只能确定一个建议 3、如果某个人认为大家同意了某 个建议,那么这个建议必须真的是被大家同意的 算法推论:情况一:如果只有一个人提出建议怎么办?如果只有一个建议被提出来那么大家必须赞同这个建议,因为如果不同意这个建议就无法确定一个年会举办地点。P1:每一个人必须同意他收到的第一个建议, 基于这样的结论会出现以下问题: 张三给王五发短信说:我建议去上海举办年会!王五给李四发短信说:我建议去广州举办年会!李四给张三发短信说:我建议去北京举办年会! 根据P1:每个人必须同意他收到的第一个建议,那么张三、李四、王五最终获得的信息是不一致的。所以再次规定:一个提议必须被大多数人同意才能生效。那么说明一个人可以同时同意多个建议,如果一个人可以同时同意多个建议最终可能出现拜占庭将军问题导致最终结果不一致。(例如:张三同意到北京举办也同意到广州举办,那么李四将获得2票一票自己的,一票张三的。他会认为自己获得多数人支持所以就确定最终是到北京举办,同理王五也会同时获得2票,也认为大家最终决定到广州举办)。? ?所以要避免出现这种问题,某个人只能同意的多个提议中的内容相同(公司举办的地址)就不会出现这种问题。最终协商结果是有2票是到同一个地方,这样就可以确认最终举办地!那么就会引出 这样的一个结论:一旦同意某个建议,那么之后同意的建议中提议公司举办年会的地址必须一致。问题出来了:如何确定什么是之前,什么 是之后所以必须为提议分配一个编号,在提议之间建立一个全序关系。 情况二:当张三、李四、王五三个人确定最终到郑州举办年会后。赵六、孙七2人由于手机没电,没收到通知,当他们2人开机后赵六给孙七发短信提议到海南举办,这个提议是孙七开机后第一次收到的提议,根据P1原则,他必须同意他接收到的第一个提议,所以孙七同意到海南举行年会。但这样就会导致孙七与张三、李四、王五他们确定的举办地点不一致。为了避免出现以上问题。对P2进行具体说明:P2a:一旦一个提议被大家同意,那么之后的人再次同意的提议中的公司举办年会的地址必须一致。也就是说,孙七在开机后同意的第一个提议必须是“到郑州举办”才不会出现信息不一致的现象。但孙七开机后必须得接受第一个提议(P1原则),并且无法干涉提议中的内容(公司举办年会的地址)。所以最好的办法通过某种方式让赵六的提议中的内容与张三、李四同意的地址相同(到郑州举行)。这样孙七同意的第一个提议就是“到郑州举办” 我们再次对P2a进行修改:P2b:一旦一个提议被大家同意,那么之后的人再次提议,提议中的公司举办年会的地址必须跟之前其它人解决的地址一致。 如何让刚开机的赵六提议的内容必须与张三、李四、王五讨论出来的一致(到郑州举行)? 我们继续对P2b进行强化修改:P2C:如果有一个编号为N的提议具有V(提议的内容),那么存在一个多数派,要么他们中所有人都没有同意编号小于N的任何提议,要么他们已经同意的所有编号小于N的提案中编号最大的那个提案具有V。 要满足P2C的要求,提议人在提议之前,首先要和多数人通信并获得他们进行的最后一次同意的提议。之后根据反馈的信息决定这次提议的内容,形成提议开始投票! 重点 所以整个投票决议分两个阶段: 准备阶段 1、提议人选择一个编号N,并将准备信息发送给多数人。2、如果收信人收到准备消息后,如果提议的编号大于它已经回复的所有准备信息。那么收信人将自己上次接受的提议内容回复给提议人,并承诺不再回复小于N的提议。 同意阶段 1、当一个提议人收到多数人反馈的信息后,就进入同意阶段。它要向反馈给它信息的人再次发送一个请同意该提议的请求。包含编号N和根据P2C决定的提议内容(如果回复中没有反馈他们已经接受过的提议内容,则可以自由决定提议内容) 2、在不违背向其它人承诺的前提下,收到该提议请求后立即同意该请求。 假设:只有User1、User2、User3 三个人决定1+1等于几! 提案阶段 User1 提案编号为 1 并发送给User2和User3。 因User2 和User3 根据P2c它们并没有接受过小于编号为1的提案。所以它们可以接受该提议,并反馈给User1 不再接受小于编号1的提案。这时User1收到多数人的回复,将进入第2阶段。(如果收到的回复并不能形成多数人,那么将再次进入阶段1) User2 提案编号为2 ;并发送给User1和User3。 因User1第一次收到提案,并且根据P2C它并没有同意过小于编号为2的提议,所以它可以接受该提议。User3由于接受过User1编号为1的提案,但User2的提案编号 2 > 1 所以User3也可以同意User2的提议,并反馈不再接受小于2的提议。User2也收到多数人的回复,将进行第2阶段。 User3提案编号为3 ;并发送给user1 和user2 . 因user1收到user3编号为3的提案 > user2编号为2的提案,所以接受user3的提案。因user2收到User3编号为3的提案 > user1 编号为1的提案,所以接受user3的提案。至此user3也收到多数人回复,将进行第2阶段。 同意阶段 user1 发送编号为1的提议,提议内容为:1+1=1;并发送给user2和User3 。 由于user2已经声明不再接受小于3的提案,所以拒绝user1的提案。由于User3已经声明不再接受小于2的提案,所以同样拒绝User1的提案。User1提议被多数人拒绝,再次`进入阶段1**. user2 发送编号为2的提议,提议内容为:1+1=2;并发送给User1和User3 由于User1已经声明不再接受小于3的提案,所以拒绝user2的提议。由于User3已经声明不再接受小于2的提案,该提案编号=2所以user3同意User2的提议。但User2并没有获得多数人的同意,所以同样进行阶段1. User3 发送编号为3的提议,提议内容为:1+1=3;并发送给User1和User2; 由于 user1 声明不再接受小于3的提案,所以同意User3的提议。由于 user2 声明不再接受小于3的提案,所以同意User3的提议。 至此最终User3可以获得多数人的同意。 Raft Raft 也是一个一致性算法,和 Paxos 目标相同。但他还有另一个名字:易于理解的一致性算法。也就是说,他的目标就是成为一个易于理解的一致性算法。以替代 Paxos 的晦涩难懂。 什么是 Raft 算法 首先说什么是 Raft 算法:Raft 是一种为了管理复制日志的一致性算法。 什么是一致性呢? Raft 的论文这么说的:一致性算法允许一组机器像一个整体一样工作,即使其中一些机器出现故障也能够继续工作下去。 这里的一致性针对分布式系统。 领导人选举 Raft 通过选举一个高贵的领导人,然后给予他全部的管理复制日志的责任来实现一致性。 而每个 server 都可能会在 3 个身份之间切换: 领导者 候选者 跟随者 而影响他们身份变化的则是 选举。当所有服务器初始化的时候,都是 跟随者,这个时候需要一个 领导者,所有人都变成 候选者,直到有人成功当选 领导者。角色轮换如下图:而领导者也有宕机的时候,宕机后引发新的 选举,所以,整个集群在选举和正常运行之间切换,具体如下图: 从上图可以看出,选举和正常运行之间切换,但请注意, 上图中的 term 3 有一个地方,后面没有跟着 正常运行 阶段,为什么呢? 答:当一次选举失败(比如正巧每个人都投了自己),就执行一次 加时赛,每个 Server 会在一个随机的时间里重新投票,这样就能保证不冲突了。所以,当 term 3 选举失败,等了几十毫秒,执行 term 4 选举,并成功选举出领导人。 接着,领导者周期性的向所有跟随者发送心跳包来维持自己的权威。如果一个跟随者在一段时间里没有接收到任何消息,也就是选举超时,那么他就会认为系统中没有可用的领导者,并且发起选举以选出新的领导者。 要开始一次选举过程,跟随者先要增加自己的当前任期号并且转换到候选人状态。然后请求其他服务器为自己投票。那么会产生 3 种结果: a. 自己成功当选 b. 其他的服务器成为领导者 c. 僵住,没有任何一个人成为领导者 注意: 每一个 server 最多在一个任期内投出一张选票(有任期号约束),先到先得。要求最多只能有一个人赢得选票。一旦成功,立即成为领导人,然后广播所有服务器停止投票阻止新得领导产生。僵住怎么办?Raft 通过使用随机选举超时时间(例如 150 - 300 毫秒)的方法将服务器打散投票。每个候选人在僵住的时候会随机从一个时间开始重新选举。以上,就是 Raft 所有关于领导选举的策略。 日志复制 一旦一个领导人被选举出来,他就开始为客户端提供服务。客户端发送日志给领导者,随后领导者将日志复制到其他的服务器。如果跟随者故障,领导者将会尝试重试。直到所有的跟随者都成功存储了所有日志。 下图表示了当一个客户端发送一个日志给领导者,随后领导者复制给跟随者的整个过程 4 个步骤: 客户端提交 复制数据到所有跟随者 跟随者回复 确认收到 领导者回复客户端和所有跟随者 确认提交。 可以看到,直到第四步骤,整个事务才会达成。中间任何一个步骤发生故障,都不会影响日志一致性。 可视化的Raft算法 github上有一个帮助大家理解算法的页面,地址是 https://raft.github.io/raftscope/index.html 建议用电脑浏览器打开,如果在手机微信里打开,需要选择“访问原网页” 我截了一个运行状态的截图,左侧显示五台服务器,右侧显示日志。 在服务器图标上点击鼠标右键会出现操作菜单。操作菜单对应服务节点的状态改变,其中request模拟客户端请求服务器集群执行任务,会在右边产生日志。 在这里插入图片描述 总结 Raft算法具备强一致、高可靠、高可用等优点,具体体现在: 强一致性:虽然所有节点的数据并非实时一致,但Raft算法保证Leader节点的数据最全,同时所有请求都由Leader处理,所以在客户端角度看是强一致性的。 高可靠性:Raft算法保证了Committed的日志不会被修改,State Matchine只应用Committed的日志,所以当客户端收到请求成功即代表数据不再改变。Committed日志在大多数节点上冗余存储,少于一半的磁盘故障数据不会丢失。 高可用性:从Raft算法原理可以看出,选举和日志同步都只需要大多数的节点正常互联即可,所以少量节点故障或网络异常不会影响系统的可用性。即使Leader故障,在选举超时到期后,集群自发选举新Leader,无需人工干预,不可用时间极小。但Leader故障时存在重复数据问题,需要业务去重或幂等性保证。 高性能:与必须将数据写到所有节点才能返回客户端成功的算法相比,Raft算法只需要大多数节点成功即可,少量节点处理缓慢不会延缓整体系统运行。 ZAB 很多人会误以为ZAB协议是Paxos的一种特殊实现,事实上他们是两种不同的协议。ZAB和Paxos最大的不同是,ZAB主要是为分布式主备系统设计的,而Paxos的实现是一致性状态机(state machine replication) 尽管ZAB不是Paxos的实现,但是ZAB也参考了一些Paxos的一些设计思想,比如: leader向follows提出提案(proposal) leader 需要在达到法定数量(半数以上)的follows确认之后才会进行commit 每一个proposal都有一个纪元(epoch)号,类似于Paxos中的选票(ballot) ZAB特性 一致性保证 可靠提交(Reliable delivery) -如果一个事务 A 被一个server提交(committed)了,那么它最终一定会被所有的server提交 全局有序(Total order) 假设有A、B两个事务,有一台server先执行A再执行B,那么可以保证所有server上A始终都被在B之前执行 因果有序(Causal order) - 如果发送者在事务A提交之后再发送B,那么B必将在A之后执行 只要大多数(法定数量)节点启动,系统就行正常运行 当节点下线后重启,它必须保证能恢复到当前正在执行的事务 ZAB的具体实现 ZooKeeper由 client、 server两部分构成 client可以在任何一个 server节点上进行 读操作 client可以在任何一个 server节点上发起 写请求,非leader节点会把此次写请求转发到 leader节点上。由leader节点执行 ZooKeeper使用改编的两阶段提交协议来保证server节点的事务一致性 ZXID ZooKeeper会为每一个事务生成一个唯一且递增长度为64位的ZXID,ZXID由两部分组成:低32位表示计数器(counter)和高32位的纪元号(epoch)。epoch为当前leader在成为leader的时候生成的,且保证会比前一个leader的epoch大 实际上当新的leader选举成功后,会拿到当前集群中最大的一个ZXID(因为数据最新),并去除这个ZXID的epoch,并将此epoch进行加1操作,作为自己的epoch。 历史队列(history queue) 每一个follower节点都会有一个先进先出(FIFO)的队列用来存放收到的事务请求,保证执行事务的顺序 可靠提交由ZAB的事务一致性协议保证 全局有序由TCP协议保证 因果有序由follower的历史队列(history queue)保证 ZAB工作模式 ZAB 协议是为分布式协调服务 ZooKeeper 专门设计的一种支持崩溃恢复的原子广播协议。在 ZooKeeper 中,主要依赖 ZAB 协议来实现分布式数据一致性。ZAB协议两种模式:消息广播和崩溃恢复`。 广播(broadcast)模式 在这里插入图片描述 leader从客户端收到一个写请求 leader生成一个新的事务并为这个事务生成一个唯一的ZXID, leader将这个事务发送给所有的follows节点,将带有 zxid 的消息作为一个提案(proposal)分发给所有 follower。 follower节点将收到的事务请求加入到历史队列(history queue)中,当 follower 接收到 proposal,先将 proposal 写到硬盘,写硬盘成功后再向 leader 回一个 ACK。 当leader收到大多数follower(超过法定数量)的ack消息,leader会发送commit请求 当follower收到commit请求时,会判断该事务的ZXID是不是比历史队列中的任何事务的ZXID都小,如果是则提交,如果不是则等待比它更小的事务的commit(保证顺序性) 恢复(recovery)模式 恢复模式大致可以分为四个阶段 ?选举、发现、同步、广播。 当leader崩溃后,集群进入选举阶段,开始选举出潜在的新leader(一般为集群中拥有最大 ZXID的节点) 进入发现阶段,follower与潜在的新leader进行沟通,如果发现超过法定人数的follower同意,则潜在的新leader将epoch加1,进入新的纪元。新的leader产生 集群间进行数据同步,保证集群中各个节点的事务一致 集群恢复到广播模式,开始接受客户端的写请求 当 leader在commit之后但在发出commit消息之前宕机,即只有老leader自己commit了,而其它follower都没有收到commit消息 新的leader也必须保证这个proposal被提交.(新的leader会重新发送该proprosal的commit消息) 当 leader产生某个proprosal之后但在发出消息之前宕机,即只有老leader自己有这个proproal,当老的leader重启后(此时左右follower),新的leader必须保证老的leader必须丢弃这个proprosal.(新的leader会通知上线后的老leader截断其epoch对应的最后一个commit的位置) ZK选举机制 每个Server会发出一个投票,第一次都是投自己。投票信息:(myid,ZXID) 收集来自各个服务器的投票 处理投票并重新投票,处理逻辑:优先比较ZXID,然后比较myid 统计投票,只要超过半数的机器接收到同样的投票信息,就可以确定leader 改变服务器状态 脑裂 ZAB为解决脑裂问题,要求集群内的节点数量为2N+1, 当网络分裂后,始终有一个集群的节点数量过半数,而另一个节点数量小于N+1, 因为选主需要过半数节点同意,所以任何情况下集群中都不可能出现大于一个leader的情况。 参考 2PC跟3PC通俗说 Paxos形象说 知乎李凯讲Paxos 不错的Paxos讲解 小灰浅谈 特别推荐一个分享架构+算法的优质内容,还没关注的小伙伴,可以长按关注一下: 长按订阅更多精彩▼如有收获,点个在看,诚挚感谢 免责声明:本文内容由21ic获得授权后发布,版权归原作者所有,本平台仅提供信息存储服务。文章仅代表作者个人观点,不代表本平台立场,如有问题,请联系我们,谢谢!

                        时间:2020-11-09 关键词: 互联网 大数据

                      • 原来10张图就可以搞懂分布式链路追踪系统原理

                        分布式系统为什么需要链路追踪? 随着互联网业务快速扩展,软件架构也日益变得复杂,为了适应海量用户高并发请求,系统中越来越多的组件开始走向分布式化,如单体架构拆分为微服务、服务内缓存变为分布式缓存、服务组件通信变为分布式消息,这些组件共同构成了繁杂的分布式网络。 微服务架构(极简版) 假如现在有一个系统部署了成千上万个服务,用户通过浏览器在主界面上下单一箱茅台酒,结果系统给用户提示:系统内部错误,相信用户是很崩溃的。 运营人员将问题抛给开发人员定位,开发人员只知道有异常,但是这个异常具体是由哪个微服务引起的就需要逐个服务排查了。 界面出现异常难以排查后台服务 开发人员借助日志逐个排查的效率是非常低的,那有没有更好的解决方案了? 答案是引入链路追踪系统。 什么是链路追踪? 分布式链路追踪就是将一次分布式请求还原成调用链路,将一次分布式请求的调用情况集中展示,比如各个服务节点上的耗时、请求具体到达哪台机器上、每个服务节点的请求状态等等。 链路跟踪主要功能: 故障快速定位:可以通过调用链结合业务日志快速定位错误信息。 链路性能可视化:各个阶段链路耗时、服务依赖关系可以通过可视化界面展现出来。 链路分析:通过分析链路耗时、服务依赖关系可以得到用户的行为路径,汇总分析应用在很多业务场景。 链路追踪基本原理 链路追踪系统(可能)最早是由Goggle公开发布的一篇论文 《Dapper, a Large-Scale Distributed Systems Tracing Infrastructure》 被大家广泛熟悉,所以各位技术大牛们如果有黑武器不要藏起来赶紧去发表论文吧。 在这篇著名的论文中主要讲述了Dapper链路追踪系统的基本原理和关键技术点。接下来挑几个重点的技术点详细给大家介绍一下。 Trace Trace的含义比较直观,就是链路,指一个请求经过所有服务的路径,可以用下面树状的图形表示。 traceId串联请求形成链路 图中一条完整的链路是:chrome -> 服务A -> 服务B -> 服务C -> 服务D -> 服务E -> 服务C -> 服务A -> chrome。服务间经过的局部链路构成了一条完整的链路,其中每一条局部链路都用一个全局唯一的traceid来标识。 Span 在上图中可以看出来请求经过了服务A,同时服务A又调用了服务B和服务C,但是先调的服务B还是服务C呢?从图中很难看出来,只有通过查看源码才知道顺序。 为了表达这种父子关系引入了Span的概念。 同一层级parent id相同,span id不同,span id从小到大表示请求的顺序,从下图中可以很明显看出服务A是先调了服务B然后再调用了C。 上下层级代表调用关系,如下图服务C的span id为2,服务D的parent id为2,这就表示服务C和服务D形成了父子关系,很明显是服务C调用了服务D。 Span使请求具有父子关系 总结:通过事先在日志中埋点,找出相同traceId的日志,再加上parent id和span id就可以将一条完整的请求调用链串联起来。 Annotations Dapper中还定义了annotation的概念,用于用户自定义事件,用来辅助定位问题。 通常包含四个注解信息: cs:Client Start,表示客户端发起请求; sr:ServerReceived,表示服务端收到请求; ss:Server Send,表示服务端完成处理,并将结果发送给客户端; cr:ClientReceived,表示客户端获取到服务端返回信息; 一次请求和响应过程 上图中描述了一次请求和响应的过程,四个点也就是对应四个Annotation事件。 如下面的图表示从客户端调用服务端的一次完整过程。如果要计算一次调用的耗时,只需要将客户端接收的时间点减去客户端开始的时间点,也就是图中时间线上的T4 - T1。如果要计算客户端发送网络耗时,也就是图中时间线上的T2 - T1,其他类似可计算。 请求和响应的时间线 带内数据与带外数据 链路信息的还原依赖于带内和带外两种数据。 带外数据是各个节点产生的事件,如cs,ss,这些数据可以由节点独立生成,并且需要集中上报到存储端。通过带外数据,可以在存储端分析更多链路的细节。 带内数据如traceid,spanid,parentid,用来标识trace,span,以及span在一个trace中的位置,这些数据需要从链路的起点一直传递到终点。通过带内数据的传递,可以将一个链路的所有过程串起来。 采样 由于每一个请求都会生成一个链路,为了减少性能消耗,避免存储资源的浪费,dapper并不会上报所有的span数据,而是使用采样的方式。举个例子,每秒有1000个请求访问系统,如果设置采样率为1/1000,那么只会上报一个请求到存储端。 数据采样 通过采集端自适应地调整采样率,控制span上报的数量,可以在发现性能瓶颈的同时,有效减少性能损耗。 存储 存储多样化 链路中的span数据经过收集和上报后会集中存储在一个地方,Dapper使用了BigTable数据仓库,常用的存储还有ElasticSearch, HBase, In-memory DB等。 业界常用链路追踪系统 Google Dapper论文发出来之后,很多公司基于链路追踪的基本原理给出了各自的解决方案,如Twitter的Zipkin,Uber的Jaeger,pinpoint,Apache开源的skywalking,还有国产如阿里的鹰眼,美团的Mtrace,滴滴Trace,新浪的Watchman,京东的Hydra,不过国内的这些基本都没有开源。 为了便于各系统间能彼此兼容互通,OpenTracing组织制定了一系列标准,旨在让各系统提供统一的接口。 下面对比一下几个开源组件,方便日后大家做技术选型。 开源组件对比 附各大开源组件的地址: zipkin? -> https://zipkin.io/ Jaeger? -> https://www.jaegertracing.io/ Pinpoint? -> https://github.com/pinpoint-apm/pinpoint SkyWalking? ->? http://skywalking.apache.org/ 接下来介绍一下Zipkin基本实现。 分布式链路追踪系统Zipkin实现 Zipkin 是 Twitter 的一个开源项目,它基于 Google Dapper 实现,它致力于收集服务的定时数据,以解决微服务架构中的延迟问题,包括数据的收集、存储、查找和展现。 Zipkin基本架构 Zipkin架构 在服务运行的过程中会产生很多链路信息,产生数据的地方可以称之为Reporter。将链路信息通过多种传输方式如HTTP,RPC,kafka消息队列等发送到Zipkin的采集器,Zipkin处理后最终将链路信息保存到存储器中。运维人员通过UI界面调用接口即可查询调用链信息。 Zipkin核心组件 Zipkin有四大核心组件 Zipkin核心组件 (1)Collector 一旦Collector采集线程获取到链路追踪数据,Zipkin就会对其进行验证、存储和索引,并调用存储接口保存数据,以便进行查找。 (2)Storage Zipkin Storage最初是为了在Cassandra上存储数据而构建的,因为Cassandra是可伸缩的,具有灵活的模式,并且在Twitter中大量使用。除了Cassandra,还支持支持ElasticSearch和MySQL存储,后续可能会提供第三方扩展。 (3)Query Service 链路追踪数据被存储和索引之后,webui 可以调用query service查询任意数据帮助运维人员快速定位线上问题。query service提供了简单的json api来查找和检索数据。 (4)Web UI Zipkin 提供了基本查询、搜索的web界面,运维人员可以根据具体的调用链信息快速识别线上问题。 总结 分布式链路追踪就是将每一次分布式请求还原成调用链路。 链路追踪的核心概念:Trace、Span、Annotation、带内和带外数据、采样、存储。 业界常用的开源组件都是基于谷歌Dapper论文演变而来; Zipkin核心组件有:Collector、Storage、Query Service、Web UI。 - END - 特别推荐一个分享架构+算法的优质内容,还没关注的小伙伴,可以长按关注一下: 长按订阅更多精彩▼如有收获,点个在看,诚挚感谢 免责声明:本文内容由21ic获得授权后发布,版权归原作者所有,本平台仅提供信息存储服务。文章仅代表作者个人观点,不代表本平台立场,如有问题,请联系我们,谢谢!

                        时间:2020-11-09 关键词: 嵌入式 分布式网络

                      • 深度揭秘垃圾回收底层,这次让你彻底弄懂她

                        Java 与 C++ 之间有一堵由内存动态分配和垃圾收集技术所围成的高墙 ---《深入理解Java虚拟机》 我们知道手动管理内存意味着自由、精细化地掌控,但是却极度依赖于开发人员的水平和细心程度。 如果使用完了忘记释放内存空间就会发生内存泄露,再如释放错了内存空间或者使用了悬垂指针则会发生无法预知的问题。 这时候 Java 带着 GC 来了(GC,Garbage Collection 垃圾收集,早于 Java 提出),将内存的管理交给 GC 来做,减轻了程序员编程的负担,提升了开发效率。 所以并不是用 Java 就不需要内存管理了,只是因为 GC 在替我们负重前行。 但是 GC 并不是那么万能的,不同场景适用不同的 GC 算法,需要设置不同的参数,所以我们不能就这样撒手不管了,只有深入地理解它才能用好它。 关于 GC 内容相信很多人都有所了解。我最早得知有关 GC 的知识是来自《深入理解Java虚拟机》,但是有关 GC 的内容单看这本书是不够的。 当时我以为我懂很多了,后来经过了一番教育之后才知道啥叫无知者无畏。 而且过了一段时间很多有关 GC 的内容都说不上来了,其实也有很多同学反映有些知识学了就忘,有些内容当时是理解的,过一段时间啥都不记得了。 大部分情况是因为这块内容在脑海中没有形成体系,没有搞懂前因后果,没有把一些知识串起来。 近期我整理了下 GC 相关的知识点,想由点及面展开有关 GC 的内容,顺带理一理自己的思路,所以输出了这篇文章,希望对你有所帮助。 有关 GC 的内容其实有很多,但是对于我们这种一般开发而言是不需要太深入的,所以我就挑选了一些我认为重要的整理出来,本来还有一些源码的我也删了,感觉没必要,重要的是在概念上理清。 本来还打算分析有关 JVM 的各垃圾回收器,但是文章太长了,所以分两篇写,下篇再发。 本篇整理的 GC 内容不限于 JVM 但大体上还是偏 JVM,如果讲具体的实现默认指的是 ?HotSpot。 正文 首先我们知道根据 「Java虚拟机规范」,Java 虚拟机运行时数据区分为程序计数器、虚拟机栈、本地方法栈、堆、方法区。 而程序计数器、虚拟机栈、本地方法栈这 3 个区域是线程私有的,会随线程消亡而自动回收,所以不需要管理。 因此垃圾收集只需要关注堆和方法区。 而方法区的回收,往往性价比较低,因为判断可以回收的条件比较苛刻。 比如类的卸载需要此类的所有实例都已经被回收,包括子类。然后需要加载的类加载器也被回收,对应的类对象没有被引用这才允许被回收。 就类加载器这一条来说,除非像特意设计过的 OSGI 等可以替换类加载器的场景,不然基本上回收不了。 而垃圾收集回报率高的是堆中内存的回收,因此我们重点关注堆的垃圾收集。 如何判断对象已成垃圾? 既然是垃圾收集,我们得先判断哪些对象是垃圾,然后再看看何时清理,如何清理。 常见的垃圾回收策略分为两种:一种是直接回收,即引用计数;另一种是间接回收,即追踪式回收(可达性分析)。 大家也都知道引用计数有个致命的缺陷-循环引用,所以 Java 用了可达性分析。 那为什么有明显缺陷的计数引用还是有很多语言采用了呢? 比如 CPython ,由此看来引用计数还是有点用的,所以咱们就先来盘一下引用计数。 引用计数 引用计数其实就是为每一个内存单元设置一个计数器,当被引用的时候计数器加一,当计数器减少为 0 的时候就意味着这个单元再也无法被引用了,所以可以立即释放内存。 如上图所示,云朵代表引用,此时对象 A 有 1 个引用,因此计数器的值为 1。 对象 B 有两个外部引用,所以计数器的值为 2,而对象 C ?没有被引用,所以说明这个对象是垃圾,因此可以立即释放内存。 由此可以知晓引用计数需要占据额外的存储空间,如果本身的内存单元较小则计数器占用的空间就会变得明显。 其次引用计数的内存释放等于把这个开销平摊到应用的日常运行中,因为在计数为 0 的那一刻,就是释放的内存的时刻,这其实对于内存敏感的场景很适用。 如果是可达性分析的回收,那些成为垃圾的对象不会立马清除,需要等待下一次 GC 才会被清除。 引用计数相对而言概念比较简单,不过缺陷就是上面提到的循环引用。 那像 CPython 是如何解决循环引用的问题呢? 首先我们知道像整型、字符串内部是不会引用其他对象的,所以不存在循环引用的问题,因此使用引用计数并没有问题。 那像 List、dictionaries、instances 这类容器对象就有可能产生循环依赖的问题,因此 Python 在引用计数的基础之上又引入了标记-清除来做备份处理。 但是具体的做法又和传统的标记-清除不一样,它采取的是找不可达的对象,而不是可达的对象。 Python 使用双向链表来链接容器对象,当一个容器对象被创建时,它被插入到这个链表中,当它被删除时则移除。 然后在容器对象上还会添加一个字段 gc_refs,现在咱们再来看看是如何处理循环引用的: 对每个容器对象,将 gc_refs 设置为该对象的引用计数。 对每个容器对象,查找它所引用的容器对象,并减少找到的被引用的容器对象的 gc_refs 字段。 将此时 gc_refs 大于 0 的容器对象移动到不同的集合中,因为 gc_refs 大于 0 说明有对象外部引用它,因此不能释放这些对象。 然后找出 gc_refs 大于 0 的容器对象所引用的对象,它们也不能被清除。 最后剩下的对象说明仅由该链表中的对象引用,没有外部引用,所以是垃圾可以清除。 具体如下图示例,A 和 B 对象循环引用, C 对象引用了 D 对象。 为了让图片更加清晰,我把步骤分开截图了,上图是 1-2 步骤,下图是 3-4 步骤。 最终循环引用的 A 和 B 都能被清理,但是天下没有免费的午餐,最大的开销之一是每个容器对象需要额外字段。 还有维护容器链表的开销。根据 pybench,这个开销占了大约 4% 的减速。 至此我们知晓了引用计数的优点就是实现简单,并且内存清理及时,缺点就是无法处理循环引用,不过可以结合标记-清除等方案来兜底,保证垃圾回收的完整性。 所以 Python 没有解决引用计数的循环引用问题,只是结合了非传统的标记-清除方案来兜底,算是曲线救国。 其实极端情况下引用计数也不会那么及时,你想假如现在有一个对象引用了另一个对象,而另一个对象又引用了另一个,依次引用下去。 那么当第一个对象要被回收的时候,就会引发连锁回收反应,对象很多的话这个延时就凸显出来了。 可达性分析 可达性分析其实就是利用标记-清除(mark-sweep),就是标记可达对象,清除不可达对象。至于用什么方式清,清了之后要不要整理这都是后话。 标记-清除具体的做法是定期或者内存不足时进行垃圾回收,从根引用(GC Roots)开始遍历扫描,将所有扫描到的对象标记为可达,然后将所有不可达的对象回收了。 所谓的根引用包括全局变量、栈上引用、寄存器上的等。 看到这里大家不知道是否有点感觉,我们会在内存不足的时候进行 GC,而内存不足时也是对象最多时,对象最多因此需要扫描标记的时间也长。 所以标记-清除等于把垃圾积累起来,然后再一次性清除,这样就会在垃圾回收时消耗大量资源,影响应用的正常运行。 所以才会有分代式垃圾回收和仅先标记根节点直达的对象再并发 tracing 的手段。 但这也只能减轻无法根除。 我认为这是标记-清除和引用计数的思想上最大的差别,一个攒着处理,一个把这种消耗平摊在应用的日常运行中。 而不论标记-清楚还是引用计数,其实都只关心引用类型,像一些整型啥的就不需要管。 所以 JVM 还需要判断栈上的数据是什么类型,这里又可以分为保守式 GC、半保守式 GC、和准确式 GC。 保守式 GC 保守式 GC 指的是 JVM 不会记录数据的类型,也就是无法区分内存上的某个位置的数据到底是引用类型还是非引用类型。 因此只能靠一些条件来猜测是否有指针指向。比如在栈上扫描的时候根据所在地址是否在 GC 堆的上下界之内,是否字节对齐等手段来判断这个是不是指向 GC 堆中的指针。 之所以称之为保守式 GC 是因为不符合猜测条件的肯定不是指向 GC 堆中的指针,因此那块内存没有被引用,而符合的却不一定是指针,所以是保守的猜测。 我再画一张图来解释一下,看了图之后应该就很清晰了。 前面我们知道可以根据指针指向地址来判断,比如是否字节对齐,是否在堆的范围之内,但是就有可能出现恰好有数值的值就是地址的值。 这就混乱了,所以就不能确定这是指针,只能保守认为就是指针。 因此肯定不会有误杀对象的情况。只会有对象已经死了,但是有疑似指针的存在指向它,误以为它还活着而放过了它的情况发生。 所以保守式 GC 会有放过一些“垃圾”,对内存不太友好。 并且因为疑似指针的情况,导致我们无法确认它是否是真的指针,所以也就无法移动对象,因为移动对象就需要改指针。 有一个方法就是加个中间层,也就是句柄层,引用会先指到句柄,然后再从句柄表找到实际对象。 所以直接引用不需要改变,如果要移动对象只需要修改句柄表即可。不过这样访问就多了一层,效率就变低了。 半保守式GC 半保守式GC,在对象上会记录类型信息而其他地方还是没有记录,因此从根扫描的话还是一样,得靠猜测。 但是得到堆内对象了之后,就能准确知晓对象所包含的信息了,因此之后 tracing 都是准确的,所以称为半保守式 GC。 现在可以得知半保守式 GC 只有根直接扫描的对象无法移动,从直接对象再追溯出去的对象可以移动,所以半保守式 GC 可以使用移动部分对象的算法,也可以使用标记-清除这种不移动对象的算法。 而保守式 GC 只能使用标记-清除算法。 准确式 GC 相信大家看下来已经知道准确意味 JVM 需要清晰的知晓对象的类型,包括在栈上的引用也能得知类型等。 能想到的可以在指针上打标记,来表明类型,或者在外部记录类型信息形成一张映射表。 HotSpot 用的就是映射表,这个表叫 OopMap。 在 HotSpot 中,对象的类型信息里会记录自己的 OopMap,记录了在该类型的对象内什么偏移量上是什么类型的数据,而在解释器中执行的方法可以通过解释器里的功能自动生成出 OopMap 出来给 GC 用。 被 JIT 编译过的方法,也会在特定的位置生成 OopMap,记录了执行到该方法的某条指令时栈上和寄存器里哪些位置是引用。 这些特定的位置主要在: 循环的末尾( 非 counted 循环) 方法临返回前 / 调用方法的call指令后 可能抛异常的位置 这些位置就叫作安全点(safepoint)。 那为什么要选择这些位置插入呢?因为如果对每条指令都记录一个 OopMap 的话空间开销就过大了,因此就选择这些个关键位置来记录即可。 所以在 HotSpot 中 GC 不是在任何位置都能进入的,只能在安全点进入。 至此我们知晓了可以在类加载时计算得到对象类型中的 OopMap,解释器生成的 OopMap 和 JIT 生成的 OopMap ,所以 GC 的时候已经有充足的条件来准确判断对象类型。 因此称为准确式 GC。 其实还有个 JNI 调用,它们既不在解释器执行,也不会经过 JIT 编译生成,所以会缺少 OopMap。 在 HotSpot 是通过句柄包装来解决准确性问题的,像 JNI 的入参和返回值引用都通过句柄包装起来,也就是通过句柄再访问真正的对象。 这样在 GC 的时候就不用扫描 JNI 的栈帧,直接扫描句柄表就知道 JNI 引用了 GC 堆中哪些对象了。 安全点 我们已经提到了安全点,安全点当然不是只给记录 OopMap 用的,因为 GC 需要一个一致性快照,所以应用线程需要暂停,而暂停点的选择就是安全点。 我们来捋一遍思路。首先给个 GC 名词,在垃圾收集场景下将应用程序称为 mutator 。 一个能被 mutator 访问的对象就是活着的,也就是说 mutator 的上下文包含了可以访问存活对象的数据。 这个上下文其实指的就是栈、寄存器等上面的数据,对于 GC 而言它只关心栈上、寄存器等哪个位置是引用,因为它只需要关注引用。 但是上下文在 mutator 运行过程中是一直在变化的,所以 GC 需要获取一个一致性上下文快照来枚举所有的根对象。 而快照的获取需要停止 mutator 所有线程,不然就得不到一致的数据,导致一些活着对象丢失,这里说的一致性其实就像事务的一致性。 而 mutator 所有线程中这些有机会成为暂停位置的点就叫 safepoint 即安全点。 openjdk 官网对安全点的定义是: A point during program execution at which all GC roots are known and all heap object contents are consistent. From a global point of view, all threads must block at a safepoint before the GC can run. 不过 safepoint 不仅仅只有 GC 有用,比如 deoptimization、Class redefinition 都有,只是 GC safepoint 比较知名。 我们再来想一下可以在哪些位置放置这个安全点。 对于解释器来说其实每个字节码边界都可以成为一个安全点,对于 JIT 编译的代码也能在很多位置插入安全点,但是实现上只会在一些特定的位置插入安全点。 因为安全点是需要 check 的,而 check 需要开销,如果安全点过多那么开销就大了,等于每执行几步就需要检查一下是否需要进入安全点。 其次也就是我们上面提到的会记录 OopMap ,所以有额外的空间开销。 那 mutator 是如何得知此时需要在安全点暂停呢? 其实上面已经提到了是 check,再具体一些还分解释执行和编译执行时不同的 check。 在解释执行的时候的 check 就是在安全点 polling 一个标志位,如果此时要进入 GC 就会设置这个标志位。 而编译执行是 polling page 不可读,在需要进入 safepoint 时就把这个内存页设为不可访问,然后编译代码访问就会发生异常,然后捕获这个异常挂起即暂停。 这里可能会有同学问,那此时阻塞住的线程咋办?它到不了安全点啊,总不能等着它吧? 这里就要引入安全区域的概念,在这种引用关系不会发生变化的代码段中的区域称为安全区域。 在这个区域内的任意地方开始 GC 都是安全的,这些执行到安全区域的线程也会标识自己进入了安全区域, 所以会 GC 就不用等着了,并且这些线程如果要出安全区域的时候也会查看此时是否在 GC ,如果在就阻塞等着,如果 GC 结束了那就继续执行。 可能有些同学对counted 循环有点疑问,像for (int i...) 这种就是 counted 循环,这里不会埋安全点。 所以说假设你有一个 counted loop 然后里面做了一些很慢的操作,所以很有可能其他线程都进入安全点阻塞就等这个 loop 的线程完毕,这就卡顿了。 分代收集 前面我们提到标记-清除方式的 GC 其实就是攒着垃圾收,这样集中式回收会给应用的正常运行带来影响,所以就采取了分代收集的思想。 因为研究发现有些对象基本上不会消亡,存在的时间很长,而有些对象出来没多久就会被咔嚓了。这其实就是弱分代假说和强分代假说。 所以将堆分为新生代和老年代,这样对不同的区域可以根据不同的回收策略来处理,提升回收效率。 比如新生代的对象有朝生夕死的特性,因此垃圾收集的回报率很高,需要追溯标记的存活对象也很少,因此收集的也快,可以将垃圾收集安排地频繁一些。 新生代每次垃圾收集存活的对象很少的话,如果用标记-清除算法每次需要清除的对象很多,因此可以采用标记-复制算法,每次将存活的对象复制到一个区域,剩下了直接全部清除即可。 但是朴素的标记-复制算法是将堆对半分,但是这样内存利用率太低了,只有 50%。 所以 HotSpot 虚拟机分了一个 Eden 区和两个Survivor,默认大小比例是8∶1:1,这样利用率有 90%。 每次回收就将存活的对象拷贝至一个 Survivor 区,然后清空其他区域即可,如果 Survivor 区放不下就放到 老年代去,这就是分配担保机制。 而老年代的对象基本上都不是垃圾,所以追溯标记的时间比较长,收集的回报率也比较低,所以收集频率安排的低一些。 这个区域由于每次清除的对象很少,因此可以用标记-清除算法,但是单单清除不移动对象的话会有很多内存碎片的产生,所以还有一种叫标记-整理的算法,等于每次清除了之后需要将内存规整规整,需要移动对象,比较耗时。 所以可以利用标记-清除和标记-整理两者结合起来收集老年代,比如平日都用标记-清除,当察觉内存碎片实在太多了就用标记-整理来配合使用。 可能还有很多同学对的标记-清除,标记-整理,标记-复制算法不太清晰,没事,咱们来盘一下。 标记-清除 分为两个阶段: 标记阶段:tracing 阶段,从根(栈、寄存器、全局变量等)开始遍历对象图,标记所遇到的每个对象。 清除阶段:扫描堆中的对象,将为标记的对象作为垃圾回收。 基本上就是下图所示这个过程: 清除不会移动和整理内存空间,一般都是通过空闲链表(双向链表)来标记哪一块内存空闲可用,因此会导致一个情况:空间碎片。 这会使得明明总的内存是够的,但是申请内存就是不足。 而且在申请内存的时候也有点麻烦,需要遍历链表查找合适的内存块,会比较耗时。 所以会有多个空闲链表的实现,也就是根据内存分块大小组成不同的链表,比如分为大分块链表和小分块链表,这样根据申请的内存分块大小遍历不同的链表,加快申请的效率。 当然还可以分更多个链表。 还有标记,标记的话一般我们会觉得应该是标记在对象身上,比如标记位放在对象头中,但是这对写时复制不兼容。 等于每一次 GC 都需要修改对象,假设是 fork 出来的,其实是共享一块内存,那修改必然导致复制。 所以有一种位图标记法,其实就是将堆的内存某个块用一个位来标记。就像我们的内存是一页一页的,堆中的内存可以分成一块一块,而对象就是在一块,或者多块内存上。 根据对象所在的地址和堆的起始地址就可以算出对象是在第几块上,然后用一个位图中的第几位在置为 1 ,表明这块地址上的对象被标记了。 而且用位图表格法不仅可以利用写时复制,清除也更加高效,如果标记在对象头上,那么需要遍历整个堆来扫描对象,现在有了位图,可以快速遍历清除对象。 但是不论是标记对象头还是利用位图,标记-清除的碎片问题还是处理不了。 因此就引出了标记-复制和标记-整理。 标记-复制 首先这个算法会把堆分为两块,一块是 From、一块是 To。 对象只会在 From 上生成,发生 GC 之后会找到所有存活对象,然后将其复制到 To 区,之后整体回收 From 区。 再将 To 区和 From 区身份对调,即 To 变成 From , From 变成 To,我再用图来解释一波。 可以看到内存的分配是紧凑的,不会有内存碎片的产生。 不需要空闲链表的存在,直接移动指针分配内存,效率很高。 对 CPU缓存亲和性高,因为从根开始遍历一个节点,是深度优先遍历,把关联的对象都找到,然后内存分配在相近的地方。 这样根据局部性原理,一个对象被加载了那它所引用的对象也同时被加载,因此访问缓存直接命中。、 当然它也是有缺点的,因为对象的分配只能在 From 区,而 From 区只有堆一半大小,因此内存的利用率是 50%。 其次如果存活的对象很多,那么复制的压力还是很大的,会比较慢。 然后由于需要移动对象,因此不适用于上文提到的保守式 GC。 当然我上面描述的是深度优先就是递归调用,有栈溢出风险,还有一种 Cheney 的 GC 复制算法,是采用迭代的广度优先遍历,具体不做分析了,有兴趣自行搜索。 标记-整理 标记-整理其实和标记-复制差不多,区别在于复制算法是分为两个区来回复制,而整理不分区,直接整理。 算法思路还是很清晰的,将存活的对象往边界整理,也没有内存碎片,也不需要复制算法那样腾出一半的空间,所以内存利用率也高。 缺点就是需要对堆进行多次搜索,毕竟是在一个空间内又标记,又移动的,所以整体而言花费的时间较多,而且如果堆很大的情况,那么消耗的时间将更加突出。 至此相信你对标记-清除、标记-复制和标记-整理都清晰了,让我们再回到刚才提到的分代收集。 跨代引用 我们已经根据对象存活的特性进行了分代,提高了垃圾收集的效率,但是像在回收新生代的时候,有可能有老年代的对象引用了新生代对象,所以老年代也需要作为根,但是如果扫描整个老年代的话效率就又降低了。 所以就搞了个叫记忆集(Remembered Set)的东西,来记录跨代之间的引用而避免扫描整体非收集区域。 因此记忆集就是一种用于记录从非收集区域指向收集区域的指针集合的抽象数据结构。根据记录的精度分为 字长精度,每条记录精确到机器字长。 对象精度,每条记录精确到对象。 卡精度,每条记录精确到一块内存区域。 最常见的是用卡精度来实现记忆集,称之为卡表。 我来解释下什么叫卡。 拿对象精度来距离,假设新生代对象 A 被老年代对象 D 引用了,那么就需要记录老年代 D 所在的地址引用了新生代对象。 那卡的意思就是将内存空间分成很多卡片。假设新生代对象 A 被老年代 D 引用了,那么就需要记录老年代 D 所在的那一块内存片有引用新生代对象。 也就是说堆被卡切割了,假设卡的大小是 2,堆是 20,那么堆一共可以划分成 10 个卡。 因为卡的范围大,如果此时 D 旁边在同一个卡内的对象也有引用新生代对象的话,那么就只需要一条记录。 一般会用字节数组来实现卡表,卡的范围也是设为 2 的 N 次幂大小。来看一下图就很清晰了。 假设地址从 0x0000 开始,那么字节数组的 0号元素代表 0x0000~0x01FF,1 号代表0x0200~0x03FF,依次类推即可。 然后到时候回收新生代的时候,只需要扫描卡表,把标识为 1 的脏表所在内存块加入到 GC Roots 中扫描,这样就不需要扫描整个老年代了。 用了卡表的话占用内存比较少,但是相对字长、对象来说精度不准,需要扫描一片。所以也是一种取舍,到底要多大的卡。 还有一种多卡表,简单的说就是有多张卡表,这里我画两张卡表示意一下。 上面的卡表表示的地址范围更大,这样可以先扫描范围大的表,发现中间一块脏了,然后再通过下标计算直接得到更具体的地址范围。 这种多卡表在堆内存比较大,且跨代引用较少的时候,扫描效率较高。 而卡表一般都是通过写屏障来维护的,写屏障其实就相当于一个 AOP,在对象引用字段赋值的时候加入更新卡表的代码。 这其实很好理解,说白了就是当引用字段赋值的时候判断下当前对象是老年代对象,所引用对象是新生代对象,于是就在老年代对象所对应的卡表位置置为 1,表示脏,待会需要加入根扫描。 不过这种将老年代作为根来扫描会有浮动垃圾的情况,因为老年代的对象可能已经成为垃圾,所以拿垃圾来作为根扫描出来的新生代对象也很有可能是垃圾。 不过这是分代收集必须做出的牺牲。 增量式 GC 所谓的增量式 GC 其实就是在应用线程执行中,穿插着一点一点的完成 GC,来看个图就很清晰了 这样看起来 GC 的时间跨度变大了,但是 mutator 暂停的时间变短了。 对于增量式 GC ,Dijkstra 等人抽象除了三色标记算法,来表示 GC 中对象三种不同状况。 三色标记算法 白色:表示还未搜索到的对象。灰色:表示正在搜索还未搜索完的对象。黑色:表示搜索完成的对象。 下面这图从维基百科搞得,虽说颜色没对上,但是意思是对的(black 画成了蓝色,grey画成了黄色)。 我再用文字概述一下三色的转换。 GC 开始前所有对象都是白色,GC 一开始所有根能够直达的对象被压到栈中,待搜索,此时颜色是灰色。 然后灰色对象依次从栈中取出搜索子对象,子对象也会被涂为灰色,入栈。当其所有的子对象都涂为灰色之后该对象被涂为黑色。 当 GC 结束之后灰色对象将全部没了,剩下黑色的为存活对象,白色的为垃圾。 一般增量式标记-清除会分为三个阶段: 根查找,需要暂停应用线程,找到根直接引用的对象。 标记阶段,和应用线程并发执行。 清除阶段。 这里解释下 GC 中两个名词的含义。 并发:应用线程和 GC 线程一起执行。并行:多个 GC 线程一起执行。 看起来好像三色标记没啥问题?来看看下图。 第一个阶段搜索到 A 的子对象 B了,因此 A 被染成了黑色,B 为灰色。此时需要搜索 B。 但是在 B 开始搜索时,A 的引用被 mutator 换给了 C,然后此时 B 到 C 的引用也被删了。 接着开始搜索 B ,此时 B 没有引用因此搜索结束,这时候 C 就被当垃圾了,因此 A 已经黑色了,所以不会再搜索到 C 了。 这就是出现漏标的情况,把还在使用的对象当成垃圾清除了,非常严重,这是 GC 不允许的,宁愿放过,不能杀错。 还有一种情况多标,比如 A 变成黑色之后,根引用被 mutator 删除了,那其实 A 就属于垃圾,但是已经被标记为黑色了,那就得等下次 GC 清除了。 这其实就是标记过程中没有暂停 mutator 而导致的,但这也是为了让 GC 减少对应用程序运行的影响。 多标其实还能接受,漏标的话就必须处理了,我们可以总结一下为什么会发生漏标: mutator 插入黑色对象 A 到白色对象 C 的一个引用 mutator 删除了灰色对象 B 到白色对象 C 的一个引用 只要打破这两个条件任意一个就不会发生漏标的情况。 这时候可以通过以下手段来打破两个条件: 利用写屏障在黑色引用白色对象时候,将白色对象置为灰色,这叫增量更新。 利用写屏障在灰色对象删除对白色对象的引用时,将白色对象置为灰,其实就是保存旧的引用关系。这叫STAB(snapshot-at-the-beginning)。 总结 至此有关垃圾回收的关键点和思路都差不多了,具体有关 JVM 的垃圾回收器等我下篇再作分析。 现在我们再来总结一下。 关于垃圾回收首先得找出垃圾,而找出垃圾分为两个流派,一个是引用计数,一个是可达性分析。 引用计数垃圾回收的及时,对内存较友好,但是循环引用无法处理。 可达性分析基本上是现代垃圾回收的核心选择,但是由于需要统一回收比较耗时,容易影响应用的正常运行。 所以可达性分析的研究方向就是往如何减少对应用程序运行的影响即减少 STW(stop the world) 的时间。 因此根据对象分代假说研究出了分代收集,根据对象的特性划分了新生代和老年代,采取不同的收集算法,提升回收的效率。 想方设法的拆解 GC 的步骤使得可以与应用线程并发,并且采取并行收集,加快收集速度。 还有往评估的方向的延迟回收或者说回收部分垃圾来减少 STW 的时间。 总的而言垃圾回收还是很复杂的,因为有很多细节,我这篇就是浅显的纸上谈兵,不要被我的标题骗了哈哈哈哈。 最后 这篇文章写了挺久的,主要是内容很多如何编排有点难,我也选择性的剪了很多了,但还是近 1W 字。 期间也查阅了很多资料,不过个人能力有限,如果有纰漏的地方请抓紧联系我。 巨人的肩膀 http://arctrix.com/nas/python/gc/ https://openjdk.java.net/groups/hotspot/docs/HotSpotGlossary.html 《The Garbage Collection Handbook 》 https://www.iteye.com/blog/user/rednaxelafx R大的博客 https://www.jianshu.com/u/90ab66c248e6 占小狼的博客 特别推荐一个分享架构+算法的优质内容,还没关注的小伙伴,可以长按关注一下: 长按订阅更多精彩▼如有收获,点个在看,诚挚感谢 免责声明:本文内容由21ic获得授权后发布,版权归原作者所有,本平台仅提供信息存储服务。文章仅代表作者个人观点,不代表本平台立场,如有问题,请联系我们,谢谢!

                        时间:2020-11-09 关键词: 嵌入式 C语言

                      • 双11的狂欢,干了这碗「流量防控」汤

                        来源 |?悟空聊架构(ID:PassJava666) 临近双十一,从 2009 年第一届双十一开始,成交量只有 5000 万,到去年 2019 年,成交量达到了 2684 亿。今年迎来了第十二届双十一,想想都挺激动。 阿里人喜欢将双十一视为 Team Building(团队建设),广为流传的一句话:打仗是最好的团建,没有参加过双十一的叫同事,参加过双十一的叫战友。 上一篇我通过三国故事讲解了服务雪崩和熔断的机制,而且自己造了一个轮子:熔断器。而这一篇会讲解被一线大厂使用的两款流量防控组件:Sentinel 和 Hystrix,以及对它们的横向对比,以及该如何选型。 本篇主要内容如下: 一、熔断&降级&限流&隔离 面对高并发的流量,我们通常会使用四种方式(熔断&降级&限流&隔离)来防止瞬时大流量对系统的冲击。而今天要介绍的这两款流量防卫兵,是专门用在这方面的。下面我先给同学扫个小盲。 什么是熔断 ? 熔断场景图@悟空聊架构 关键字:断路保护。比如 A 服务调用 B 服务,由于网络问题或 B 服务宕机了或 B 服务的处理时间长,导致请求的时间超长,如果在一定时间内多次出现这种情况,就可以直接将 B 断路了(A 不再请求B)。而调用 B 服务的请求直接返回降级数据,不必等待 B 服务的执行。因此 B 服务的问题,不会级联影响到 A 服务。 什么是降级 ? 降级场景图 关键字:返回降级数据。网站处于流量高峰期,服务器压力剧增,根据当前业务情况及流量,对一些服务和页面进行有策略的降级(停止服务,所有的调用直接返回降级数据)。以此缓解服务器资源的压力,保证核心业务的正常运行,保持了客户和大部分客户得到正确的响应。降级数据可以简单理解为快速返回了一个 false,前端页面告诉用户“服务器当前正忙,请稍后再试。” 什么是限流? 限流场景图 对请求的流量进行控制, 只放行部分请求,使服务能够承担不超过自己能力的流量压力。 熔断和降级的相同点? 熔断和限流都是为了保证集群大部分服务的 可用性和 可靠性。 防止核心服务崩溃。 给终端用户的感受就是某个功能不可用。 熔断和降级的不同点? 熔断是被调用方出现了故障, 主动触发的操作。 降级是基于全局考虑,停止某些正常服务,释放资源。 什么是隔离? 每个服务看作一个 独立运行的系统,即使某一个系统有问题,也不会影响其他服务。 二、Hystrix Hystrix 是什么 Hystrix:高可用性保障的一个框架。由 Netflix 出品(Netflix可以理解为国内的爱奇艺等视频网站)。 Hystrix 的历史 2011 年,其中的 API 团队为了提升系统的可用性和稳定性,发展出了 Hystrix 框架。 2012 年,Hystrix 区域比较成熟稳定。其他团队也开始使用 Hystrix。 2018 年 11 月,Hystrix在其 Github 主页宣布,不再开放新功能,推荐开发者使用其他仍然活跃的开源项目。但是 Hystrix 价值依旧很大,功能强大,国内很多一线互联网公司在使用。 Hystrix 设计理念 阻止服务的雪崩效应。 快速失败和快速恢复。 优雅降级。 使用资源隔离技术,如 bulkhead(舱壁隔离技术)、swimlane(泳道技术)、circuit breaker(断路技术)。 近实时的监控、报警及运维操作。 Hystrix 线程池隔离技术 使用线程池隔离,比如说有 3 个服务 A、B、C,每个服务的线程池分配 10,20,30个线程,当 A 服务线程池中的 10 个线程都拿出来使用后,如果调用服务 A 的请求量增加,还想再增加线程是不行的,因为 A 服务分配的线程已经用完了,不会拿其他的服务的线程,这样就不会影响其他服务了。Hystrix 默认使用线程池隔离模式。 线程池隔离技术 线程池隔离技术优点 依赖的服务都有隔离的线程池,即使自己的线程池满了,也不会影响任何其他其他的服务调用。 线程池的健康状态会上报,可以近实时修改依赖服务的调用配置。 线程池具有异步特性,可以构建一层异步调用层。 具有超时检测的机制,尤其在服务间调用特别有用。 线程池隔离技术缺点 线程池本身就会带来一些问题,比如 线程切换,线程管理,无疑增加了 CPU 的开销。 如果线程池中的线程利用率很低,则无疑是一种浪费。 Hystrix 信号量隔离技术 如下图所示:简单来说就是一个池子里面放着一定数量的信号量,服务 A 每次调用服务 B 之前,需要从池子里面申请信号量,申请到了,才能去调用 B 服务。 获取信号量 线程池隔离和信号量的场景对比 线程池隔离技术 ,适合大部分场景,但需要设置服务的超时时间。 信号量隔离技术 ,适合内部比较复杂的业务,不涉及网络请求问题。 三、Sentinel 3.1、Sentinel 是什么 Sentinel:面向分布式服务架构的流量控制组件,主要以流量为切入点,从限流、流量整形、熔断降级、系统负载保护、热点防护等多个维度来帮助开发者保障微服务的稳定性。 3.2、Sentinel 的历史 2012 年,Sentinel 诞生,主要功能为入口流量控制。 2013-2017 年,Sentinel 在阿里巴巴集团内部迅速发展,成为基础技术模块,覆盖了所有的核心场景。Sentinel 也因此积累了大量的流量归整场景以及生产实践。 2018 年,Sentinel 开源,并持续演进。 2019 年,Sentinel 朝着多语言扩展的方向不断探索,推出 C++ 原生版本,同时针对 Service Mesh 场景也推出了 Envoy 集群流量控制支持,以解决 Service Mesh 架构下多语言限流的问题。 2020 年,推出 Sentinel Go 版本,继续朝着云原生方向演进。 3.3、Sentinel 的特征 丰富的应用场景。 支撑阿里的双十一核心场景,如秒杀、消息削峰填谷、集群流量控制、实时熔断下游不可用。 完备的实时监控。 可以看到接入应用的单台机器秒级数据,以及集群的汇总情况。 广泛的开源生态。 Spring Cloud、Dubbo、gRPC 都可以接入 Sentinel。 完善的 SPI 扩展点。 实现扩展接口来快速定制逻辑。 用一张图来总结: Sentilel 的主要特性 3.4、Sentinel 的组成 核心库(Java 客户端)不依赖任何框架/库,能在所有的 Java 运行时环境运行,且对 Spring Cloud、Dubbo 等框架有较好的支持。 控制台(Dashboard)基于 Spring Boot 开发,打包后可以直接运行,不需要额外的 Tomcat 等应用容器。 3.5、Sentinel 的资源 Sentinel 中的资源是核心概念,可以是 Java 应用程序中的任何内容,可以是提供的服务,甚至是一段代码。 可以通过 Sentinel API 定义的代码,就是资源,能够被 Sentinel保护起来。可以如下几种方式来标识资源: 方法签名。 URL。 服务名称等。 3.6、Sentinel 的设计理念 Sentinel 作为一个流量控制器,可以根据需要把随机的请求调整成合适的形状,如下图所示: 流量整形 四、对比 4.1、隔离设计上对比 Hystrix Hystrix 提供两种隔离策略,线程池隔离和信号量隔离。 Hystrix 中最推荐的也是最常用的是线程池隔离。线程池隔离的好处是隔离度很高,不会影响其他资源,但是线程本身也有自己的问题,线程上下文切换时比较耗 CPU 资源的,如果对低延时要求比较高,影响还是挺大的,而且创建线程是需要分配内存的,创建的线程越多,需要分配的内存也会更多。而且如果对每个资源都创建一个线程池,那线程切换会带来更大的损耗。 而 Hystrix 的信号量隔离,可以对某个资源调用的并发数进行限制,轻量级的,不用显式创建线程池,但缺点是不能对慢调用进行自动降级,只能等客户端那边超时,还是有可能出现级联阻塞的情形。 Sentinel Sentinel 可以通过并发线程数模式的流量控制来提供信号量隔离的功能,而且它还具备响应时间的熔断降级模式,防止过多的慢调用占满并发数而影响整个系统。 4.2、熔断降级的对比 Sentinel 和 Hystrix 都是基于熔断器模式。都支持基于异常比率来进行熔断,但 Sentinel 更强大,可以基于响应时间、异常比率和异常数来进行熔断降级。 4.3、实时统计的对比 Sentinel 和 Hystrix 都是基于滑动窗口进行实时统计,但 Hystrix 是基于 RxJava 的事件驱动模型,在服务调用成功/失败/超时的时候发布响应的事件,通过一系列的变换和聚合最终得到实时的指标统计数据流,可以被熔断器或 Dashboard 消费。而 Sentinel 是基于 LeapArray 的滑动窗口。 五、Sentinel 的突出特性 除了上面提到的 三大对比外,Sentinel 还有一些 Hystrix 不具备的功能。 5.1、流量控制 流量控制: 其原理是监控应用流量的 QPS 或并发线程数等指标,当达到指定的阈值时对流量进行控制,以避免被瞬时的流量高峰冲垮,从而保障应用的高可用性。 Sentinel 可以基于QPS/并发数进行流量控制,也可以基于调用关系进行流量控制。 基于 QPS 进行流量控制有以下几种方式: 直接拒绝: 当QPS 超过一定阈值时,直接拒绝。适用于对系统处理能力确切已知的情况。 慢启动预热: 当系统长期处于低水位的情况下,当流量突然增加时,直接把系统拉升到高水位可能瞬间把系统压垮。通过"冷启动",让通过的流量缓慢增加,在一定时间内逐渐增加到阈值上限,给冷系统一个预热的时间,避免冷系统被压垮。 慢启动预热模式原理图 匀速排队: 请求以均匀的速度通过,对应的是漏桶算法。 匀速排队模式原理图 基于调用关系的流量控制: 根据调用方限流。 根据调用链路入口限流:链路限流。 根据具有关系的资源流量限流:关联流量限流。 5.2、系统自适应限流 Sentinel 系统自适应限流从整体维度对应用入口流量进行控制,借助 TCP BBR 思想,结合应用的 Load、CPU 使用率、总体平均 RT、入口 QPS 和并发线程数等几个维度的监控指标,通过自适应的流控策略,让系统的入口流量和系统的负载达到一个平衡,让系统尽可能跑在最大吞吐量的同时保证系统整体的稳定性。 自适应限流原理图 我们把系统处理请求的过程想象为一个水管,到来的请求是往这个水管灌水,当系统处理顺畅的时候,请求不需要排队,直接从水管中穿过,这个请求的RT是最短的;反之,当请求堆积的时候,那么处理请求的时间则会变为:排队时间 + 最短处理时间。 推论一: 如果我们能够保证水管里的水量,能够让水顺畅的流动,则不会增加排队的请求;也就是说,这个时候的系统负载不会进一步恶化。 推论二:?当保持入口的流量是水管出来的流量的最大的值的时候,可以最大利用水管的处理能力。 5.3、 实时监控和控制面板 Sentinel 提供一个轻量级的开源控制台,它提供机器发现以及健康情况管理、监控(单机和集群),规则管理和推送的功能。 Sentinel 控制台 5.4、 发展及生态 Sentinel 针对 Spring Cloud、Dubbo、gRPC 都进行了适配,引入依赖和简单的配置即可快速接入 Sentinel,相信 Sentinel 将是未来流量防控的一大利器。我比较看好 Sentinel。 5.5、 Sentinel 和 Hystrix 对比总结 Hystix 和 Sentinel 对比总结 写在最后 有读者问我秒杀系统该怎么设计,在之前的文章中,我已经揭秘了秒杀系统的架构设计,下面我还是总结下秒杀系统关注的八大点: 服务单一职责、独立部署 库存预热、快速扣减 秒杀链接加密 动静分离 恶意请求拦截 流量错峰 限流&熔断&降级 队列削峰 特别推荐一个分享架构+算法的优质内容,还没关注的小伙伴,可以长按关注一下: 长按订阅更多精彩▼如有收获,点个在看,诚挚感谢 免责声明:本文内容由21ic获得授权后发布,版权归原作者所有,本平台仅提供信息存储服务。文章仅代表作者个人观点,不代表本平台立场,如有问题,请联系我们,谢谢!

                        时间:2020-11-09 关键词: 互联网 数据库

                      • 混频器基础概念大盘点,快拿出你的小本本~

                        免责声明:本文内容由21ic获得授权后发布,版权归原作者所有,本平台仅提供信息存储服务。文章仅代表作者个人观点,不代表本平台立场,如有问题,请联系我们,谢谢!

                        时间:2020-11-09 关键词: 混频器 数字信号

                      • 挑战不可能!第十五届全国大学生智能汽车竞赛全满结束

                        昨天晚上从珠海来到安徽合肥职业技术学院。在这里举办第十五届全国大学生智能汽车竞赛--安徽赛区暨安徽省第十三届智能汽车竞赛。 这场2020年安徽省教育厅批复的的第一场线下高校学生学科经竞赛是第十五届全国大学生智能汽车竞赛的收官之赛。 今天(11月8日)进行安徽赛区国赛总决赛队伍成绩认定竞赛。 比赛完之后,第十五届智能车竞赛八个分、省赛区、全国总决赛的比赛正式结束了。 虽然由于疫情,安徽赛区最后一个举办了分赛区比赛。昨天安徽合肥工业大学的吴晔教授给我历数了在举办智能车竞赛的十五届的历程中的很多个首次: 1. 安徽赛区是首个独立举办分赛区比赛的省赛区。 2. 安徽赛区曾第一个在军队院校举办竞赛。 3. 安徽赛区第一个在专科学校举办过竞赛。 4. 安徽赛区第一个有专科学校参赛队伍进入全国总决赛,并获得过总决赛的一等奖。 5. 明年安徽赛区也将会首次将竞赛安排在医科院校举办。 智能车竞赛在安徽赛区吸引了越来越多的高校参赛队伍,也培养了大批的高校学子对工科产生了高昂的志趣。 在昨天的比赛现场中,很多同学展现了自己制作的车模优异的性能的性能。比如下面这辆直立节能车跑出了17秒多的优异成绩。 在昨天省赛完之后,竞赛志愿者同学们又开始布置了今天国赛赛道。进入国赛的队伍将会在今天下午进行五个赛项的总决赛赛项比赛。 比赛完之后将进行国赛颁奖仪式。在这里预祝在学期中备赛的队伍能够取得好成绩。 当然今年的比赛,留给大比分参赛队伍准备比赛的时间并不多,并且一边上课一边调车。 下面是在朋友圈里看到一个队伍是如何“八天挑战不可能”的。 “在学长的帮助下,连续调了大概一个星期的车,连续数天4点多休息,每天被专业课和作业逼迫着。” “在今天终于得到了回报,车子完赛用了19s,因为没有完全进入车库,罚了5s,最终成绩24s,应该可以获得省奖。” “休息了,晚上要补落下的光学实验,还要准备下个星期的4门考试。” 免责声明:本文内容由21ic获得授权后发布,版权归原作者所有,本平台仅提供信息存储服务。文章仅代表作者个人观点,不代表本平台立场,如有问题,请联系我们,谢谢!

                        时间:2020-11-09 关键词: 汽车电子 AI

                      • 浅谈随机振动试验:随机有效推力和正弦推力的关系

                        在浏览振动试验机的产品目录时,同一台设备,可以看到随机推力最大有效值一般都在正弦最大推力的80%附近。另外,在计算随机推力的时候,一般厂家都会推荐随机加速度的有效值控制在正弦最大加速度的1/3以下。下面个人就对这两句话的理解,进行说明。 正弦振动试验 当初相位为零的时候,其函数式可以表示为, A(t)= Ap sin(ωt) 其中,Ap为正弦加速度最大值,角速度ω =2π/T。对应一个周期(T)的 函数式代入,通过积分计算得到(计算结果适用于整个正弦试验过程), 随机振动试验 假设随机振动是一个平稳的、遍历的和满足正态分布的过程,一般随机振动的位移平均值为0,所以其位移的概率密度函数为, p(x)---振动位移幅值概率密度函数, x---位移瞬时幅值 ρ---位移标准偏差 随机振动位移的产生是由振动控制仪通过内部的计算产生,对应的加速度和速度也可以理解为符合正态分布,所以加速度的概率密度函数为 p(A)---振动加速度幅值概率密度函数, A---加速度瞬时幅值 σ---加速度标准偏差 通过加速度的概率密度函数可以计算随机振动加速度的 其实,随机的绝对平均值和正弦的绝对平均值是可以同样看待的,两者相等即表示振动的能量相同。于是可以得到, 上式中可以看出,当正弦最大加速度为Ap时,对应的随机振动加速度有效值为其的80%。通过牛顿第二定律,可以计算出随机推力最大有效值一般都在正弦最大推力的80%附近。 接下来,我们来理解在计算随机试验推力的时候,随机加速度的有效值控制在正弦最大加速度的1/3以下这句话。因为随机振动时控制仪产生的加速度符合正态分布,μ为加速度平均值(一般μ= 0),σ为加速度标准方差,也就是加速度有效值(均方根值Arms随机)。 通过计算我们可以知道,随机加速度落在±σ范围内的概率是68.27%,在±2σ内的概率是95.45%,在±3σ内的概率是99.73%,σ对应的系数1、2、3…就是控制仪里面的削波系数。所以,当通过PSD计算出随机加速度有效值后,实际在试验中产生的瞬时加速度为有效值的±3倍(偶尔也会±5~6倍,负值代表反方向)。这就是计算推力时,随机加速度的有效值控制在正弦最大加速度的1/3以下的由来,当然削波系数设定为3。当有效值较小的时候,削波系数可以使用控制仪中的默认值。 综上所述,在随机试验计算推力的时候,主要还是需要考虑有效值,尽量将加速度有效值控制在正弦最大加速度的1/3以下,也就是说当试验机的正弦最大加速度为1000m/s2时,其对应的随机加速度有效值最大333.3m/s2,即随机试验对应的最大有效推力是正弦试验最大推力的1/3。这是一个最保险的方法,一般不会损坏振动试验机。 备注:图片和部分文字等来源于网络,如有侵权,请联系作者本人。 长按二维码识别关注我们 免责声明:本文内容由21ic获得授权后发布,版权归原作者所有,本平台仅提供信息存储服务。文章仅代表作者个人观点,不代表本平台立场,如有问题,请联系我们,谢谢!

                        时间:2020-11-09 关键词: 振动 物理学

                      • 瀚宇彩晶建立Mini/Micro LED生产线

                        液晶面板制造商瀚宇彩晶显示透露,将斥资27.7亿新台币(合9550万美元),收购旗下和鑫光电的部分厂房及设备,以兴建Mini/Micro Led生产线。 瀚宇彩晶是和鑫光电的最大股东,持股比例为26.6%。 瀚宇彩晶买下了和鑫光电6层大楼的前三层。瀚宇彩晶指出,最上面的三层目前被和鑫光电的触控传感器生产线占据,该生产线面向智能手机和平板电脑面板。 瀚宇彩晶表示,该公司一直在与设备和材料供应商合作,准备生产用于可穿戴设备、平板电脑、笔记本电脑和汽车显示器的微型背光面板,并补充说,该公司还计划进入Mini LED面板的开发和生产阶段。 瀚宇彩晶公布,2020年第三季综合营收为新台币54.38亿元,毛利率为36.86%,净利润为新台币16.43亿元。今年1-9月,瀚宇彩晶录得综合营收125.11亿新台币,毛利率17.56%,营业利润8.531亿新台币,净利润10.71亿新台币。 在第三季度,瀚宇彩晶的19英寸平板出货量为464.1万。出货量包括1.55亿块中小尺寸面板,55万块大尺寸面板和12万台Hannspree自有品牌液晶显示器。 在第三季度的收入中,6英寸及以下的手机面板占44%,6.2-10.1英寸的占43%,11英寸以上的占13%。 和鑫光电公布第三季度合并营收为新台币7060万,毛利率为19.46%,净利润为7360万,1-9月合并营收为新台币21.52亿,毛利率为19.17%,净利润为新台币1.393亿。 免责声明:本文内容由21ic获得授权后发布,版权归原作者所有,本平台仅提供信息存储服务。文章仅代表作者个人观点,不代表本平台立场,如有问题,请联系我们,谢谢!

                        时间:2020-11-09 关键词: LED 液晶面板

                      • 164亿欧元GDP、22万+工作岗位,华为对欧洲的贡献还不止于此

                        11月5日-6日,以“携手创新,共筑未来”为主题的华为2020欧洲创新日在波兰举办,来自欧洲各高校、研究所、企业、初创社区以及国际组织的代表和意见领袖“齐聚一堂”,分享了借助人工智能、5G、云和物联网等技术构造万物互联、万物感知、万物智能的世界,深入探讨了如何与当地人才进行更紧密的合作,推动人才培养和科技创新,构建更美好的社会。 活动期间,牛津经济研究院发布了《华为对欧洲经济影响力报告》,从GDP、就业、税收、研发投入等多个方面对华为在欧洲整体区域经济产生的影响进行评估。牛津经济研究院欧洲和中东地区经济影响力咨询主管Pete Collings在解读报告时指出,2019年华为在欧洲的经营活动为欧洲带来了164亿欧元的经济收益,直接或通过其供应链间接提供了22.43万个工作岗位,其研发活动及投入对欧洲的经济增长以及产业发展有着至关重要的作用。 ? GDP贡献:创造164亿欧元经济收益,直接贡献28亿欧元 报告指出,华为对欧洲(包括欧盟、冰岛和瑞士等地)GDP的助力主要来源于三个方面,分别是运营支出带来的直接贡献(Direct),从欧洲供应商处购买产品和服务带来的间接贡献(Indirect),以及支付员工工资继而刺激经济活动带来的诱发贡献(Induced)。 ? 近五年的时间里,华为对欧洲的GDP贡献持续增加,在2019年更是创造了一个历史最高点。这主要是由于华为对于欧洲市场的投入不断增大,采购支出以及对设备与员工的投资都在不断增加。报告显示,2019年,华为对于欧洲GDP的贡献总额为164亿欧元,过去五年平均增长率为19%。 ? 其中,华为2019年的直接贡献额为28亿欧元,过去五年平均增长率为11.4%。2015-2019年,华为在欧洲供应商处的采购金额接近310亿欧元,其中2019年的消费额占比达30%,由此带来的对GDP的间接贡献金额高达73亿欧元。通过在欧洲供应商处购买产品,华为为多个高科技领域的欧洲公司的经济活动提供了有力支持,继而有力地推动了经济发展。 ? 报告还显示,2019年华为对欧洲GDP的总贡献在各个国家间分布广泛,从贡献绝对值来看,GDP贡献主要显现在英国、德国、法国、瑞士和意大利等国家。 ? 就业贡献:创造22.43万个工作岗位,直接雇佣1.38万名员工 不止是GDP的增长,报告指出过去的一年里华为对于欧洲就业市场的贡献也十分显著。目前,华为在27个欧盟成员国以及冰岛、挪威和瑞士等地都设有办事处,2019年华为向欧洲提供了共计22.43万个工作岗位,过去五年平均增长率为17%。 ? 在这些工作岗位中,华为在欧洲的实体公司雇佣的固定员工和合同员工共计1.38万名,比2015年增加了近30%,增长速度大大超过了欧洲每年平均的就业增长率。此外,华为通过全球供应链中的欧洲公司提供的岗位为11.2万个,进一步催生的诱发岗位为9.85万个。 ? 据报告统计,在过去五年时间里,华为向其欧洲员工支付的总工资实际价值超过60亿欧元,而供应链中受雇员工获得的实际工资总额超过了120亿欧元。这些被支付的工资可以作为消费者的支出提供资金,反过来支持休闲、零售等经济活动,使欧洲各行各业的发展都能够从中受益。 ? 从国家分布看,华为对劳动市场的影响力遍布欧洲,其中英国、德国、法国以及意大利等国家受益尤其显著。 研发投入:10年研发投入超10亿美元,2019专利申请量第一 报告还指出,除了经济和就业等方面的巨大贡献外,华为在欧洲持续的研发活动及投入,对于欧洲大陆的长期发展来说意义更大。欧盟当前正在科技领域推进总投资金额高达1000亿欧元的“地平线欧洲计划”(Horizon Europe Programme),希望吸引公共资金用于研发创新。 ? 作为全球最大的创新研发投资者之一,华为在全球和欧洲的研究投入一直非常可观。报告援引权威机构的统计数据称,2018-2019年度,华为的研发投入在全球排名第五,金额高达127亿欧元。自2016年起,华为在全球的研发投入便一直处在TOP10之列。 ? 在欧洲,自2010年以来,华为在其遍布欧洲12个国家和地区的23个研究所推行“创新研究计划”(Innovation Research Programme),累计投入已超过10亿美元。在欧洲专利局2019专利申请排名中,华为专利申请量位居榜首。 ? “研发对经济很重要,研发不仅为公司本身带来产品改进、提高效率及提高利润等收益,而且对整个经济也能带来溢出效应和收益。” Pete Collings强调,“经济生产力的提升非常关键,其可以推动长期经济增长。华为在欧洲的研发投入有助于促进欧洲的长期经济增长。” ? 小结: 综上可见,欧洲市场支撑了华为公司业务的全球化扩展,华为在欧洲的长期投入也助推了欧洲经济的繁荣。无论是在GDP贡献、就业贡献,还是研发投入等层面,华为直接、间接和诱发产生的经济效益正逐年增长,且呈现出极高的增长速度,成为助推欧洲经济发展的重要力量。这样的确定性贡献,在当下全球不确定性的大环境下,对欧洲的意义尤其重大。近年来,欧洲致力于数字化产业发展,试图在包括人工智能、物联网、高性能计算与算法等相关领域实现数字主权。将越来越多的数字技术融入到人们的日常生活,是欧洲许多国家政府的目标。作为欧洲本地价值的创造者与数字生态的推动者,华为持续加码投入欧洲,除了带来巨大的GDP和就业贡献外,无疑还将为欧洲本地培养大量ICT人才,进一步夯实欧洲数字化的“地基”,共创欧洲美好未来! 免责声明:本文内容由21ic获得授权后发布,版权归原作者所有,本平台仅提供信息存储服务。文章仅代表作者个人观点,不代表本平台立场,如有问题,请联系我们,谢谢!

                        时间:2020-11-09 关键词: 物联网 人工智能 5G

                      • WiFi 7要来了,但它真的靠谱吗?

                        本文来源:钟林谈芯、科技美学、ZBT科研站、物联传媒 没有最快,只有更快。 WIFI6刚火,WIFI7就来了。 继WIFI6(802.11ax)推出之后,802.11be(Extremely High Throughput)新的标准被提出,以此类推,WIFI联盟将会把802.11be标准命名为WIFI7。 什么是WIFI7? 你可能会想,这WIFI 6还没开始普及怎么就开始研究WIFI 7了呢?这倒不用疑惑,因为如今WIFI 7还停留在制定标准阶段,具体商用普及时间可能要到五年之后了。WIFI 7 特点是速度比WIFI 6更快,以及信号检测非常灵敏。目前最有可能成为Wi-Fi 7的,是正在开发中的IEEE 802.11be标准,它是Wi-Fi 6,也就是802.11ax标准的直系血亲。 1 在WIFI 7标准中,会增加6G频段来拓宽网络传输的带宽,WIFI 7 可以同时工作在2.4G、5G、6G 3个频段,结合CMU-MIMO技术,WIFI 7 理论上最高可以达到30Gbps的网络传输速度,而WiFi 6的最高网络传输速度只有9.6Gbps。 在802.11ax也就是WIFI 6中,标准使用的是1024-QAM调制,而802.11be(WIFI 7)预计将继续升级调制方式,直接使用4096-QAM,这将扩大传输数据容量,为最高30Gbps的速率打好基础。 不过WIFI 7并不是十全十美,比如说WIFI 7的320MHz的超高频宽是必须借助于新的6GHz无线频段才能实现。这也就是说在兼容WiFi6的频段上,802.11be并不能发挥出最大速度;而在802.11be技术真正满速的无线频段上,其实是不能向下兼容以往的WiFi标准的。 而且如果想真正享受到技术所号称高达30Gbps的网络带宽,你需要一款有足足16根天线的超级无线网卡,其次还需要购买一款有着16根天线的无线路由器。需要如此高规格设备的原因,一是802.11be将数据流并发数量(MIMO)从本世代的最大8条翻倍到最大16条,二是802.11be新增了“协同多用户多入多出(CMU-MIMO)”功能。 WIFI7对于射频前端的市场会 信息技术日新月异,造福了人类,苦了电子和芯片行业打工人。但也正是这样的苦,我们这些产业打工人才有机会。 不同的wifi技术对于射频产品的要求也不一样,越往WIFI6、WIFI7走,对射频前端的要求就越高,对工艺的要求也越高。 WIFI4,802.11n: 2.4G路由器走入千家万户,射频前端的机会就是2.4G FEM,主要是对高功率的需求,中低功率已经被集成,Skyworks和Qorvo已经不再更新这个标准的产品,早期产品采用砷化镓工艺。 WIFI5,802.11ac: 这个标准引入了5.8GHz频段,开启2.4G和5.8G双频路由器。射频前端机会有2.4G FEM和5.8G FEM。 2.4G FEM,刚开始每个路由器都会加,后来路由器平台集成的射频前端输出功率也能到19~20dBm,基本上就不外加了。Skyworks提供过砷化镓的2.4G FEM,也提供过锗硅(SiGe)工艺的2.4G FEM。Qorvo坚持砷化镓工艺。 5.8G FEM,7年前Skyworks第一次推出砷化镓工艺的5.8G FEM,输出功率20dBm@EVM-35dB。后来做了一颗2*2封装的锗硅(SiGe)工艺5.8G FEM,看下来是不成功的,成本还不错,性能要差一些。Qovor坚持做砷化镓工艺5.8G FEM。后来MTK平台采用DPD功能,把集成5.8G FEM输出功率也做到了19dBm,外加5.8G FEM的机会就少了。 WIFI6,802.11ax: 2.4G FEM,Skyworks和Qorvo都一致地转向了锗硅(SiGe)工艺,性能测试下来还不错。锗硅(SiGe)工艺最好的还是GF,也是国外厂家选择的代工厂。锗硅(SiGe)工艺研发成本高,设计难度大,国内熟悉这个工艺的研发人才稀缺,好处是设计阶段的仿真比较准,生产一致性高,但成本对比下来跟砷化镓差不多。 锗硅(SiGe)工艺开发的FEM电流好那么一点,三伍微研发的砷化镓WIFI6 FEM与SKY最新的FEM对比,三伍微FEM工作电流150mA@3.3V@DVM-43dB,而SKY FEM工作电流为135mA@3.3V@DVM-43dB,差15mA。 5.8G FEM,Skyworks和Qorvo都采用砷化镓工艺,国外做过这两种工艺的研发体会是,两种工艺都能做,但锗硅(SiGe)工艺相比砷化镓工艺总是差那么一点点。随着对设计和性能的要求越高,锗硅(SiGe)工艺越力不从心,不得不采用砷化镓工艺。 在WIFI6主芯片技术上,尤其是底层的软件协议,MTK与高通和博通还是有差距的,国内芯片厂家差距更大,国内能在2年后量产WIFI6主芯片就已经很不错了。 MTK的优势也很明显,技术均衡,在基带芯片、软件协议、射频收发、射频前端等技术上都很不错,尤其是在射频前端技术上世界领先。 因此,MTK WIFI6低端方案可以不采用2.4G WIFI6 FEM和5.8G WIFI6 FEM,射频前端全部集成实现功率输出。高通和博通做不到,国内其他厂家更做不到。 当然,随着WIFI6的到来,不同国家的频段发生了改变,中国维持不变,估计以后也不会改变。但美国和巴西已经把WIFI频段拓展到了7.2GHz,日本可能会跟进。欧洲把频段上升到6GHz。由于频段的改变,WIFI FEM前端芯片也需要改变,频率越高,带宽越宽,对设计和工艺的要求越高,工艺选择依然是砷化镓。同时,射频前端被集成的难度越来越大。 WIFI7,802.11.be: 2.4G FEM,锗硅(SiGe)工艺和砷化镓工艺都会存在。5.8G FEM,个人认为只能是砷化镓工艺,主芯片集成射频前端的难度更大了,FEM外挂将是主流。 频率越高、带宽越宽、速率越快,芯片研发的难度越大,砷化镓工艺相对还是有优势的,所以砷化镓将是WIFI FEM的主流工艺和未来方向。 尽管MTK很厉害,持续地挑战集成射频前端,但事实是WIFI FEM的市场需求规模不是越来越小,反而是越来越大。对路由器市场来讲,集成不会是主流,随着WIFI技术不断向前发展,市场应用越来越广,对射频前端的要求越来越高,射频前端FEM机会多多。 WIFI7真的靠谱吗? 尽管从目前的描述来看,“WIFI7”是一项足以令人兴奋的技术,可问题在于,它真的就是“WiFi7”吗? 请注意,我们并不否认次时代的WiFi标准会有30Gbps甚至更高的带宽规格,但“次世代WiFi标准”与“WiFi7”之间,却或许并不能直接划等号。 为什么? 因为次时代的WiFi标准不止一个,而“WiFi7”只不过是WiFi联盟面向普通消费者宣传用的一个商业符号。具体由哪一种未来标准来担当“WiFi7”,至少目前是还没有定论的。 就算是WiFi7横空出世,以11be的价格,怕是没几个人能负担得起。 说回WIFI6,与 5G 相当,“Wi-Fi 6”成为2020年各个手机厂商发布新机的必备标签。 据统计,几乎所有国内手机厂商都在近三个月发布了搭载Wi-Fi 6功能的新品。而在智能家居领域,三星的全球首台Wi-Fi 6电视已经问世,未来更多设备,如冰箱、空调也有望加上这一标签。 有人说,2020年是Wi-Fi 6商用元年。这项长期没什么存在感的技术,开始频频登上微博热搜。2月8日,雷军强调小米10是首款支持8×8 MU-MIMO的手机,MU-MIMO是Wi-Fi 6的一种新特性,能够极大加快传输速度。 值得一提的是,要想享受Wi-Fi 6带来的新网速,路由器也得和终端设备一起升级。支持Wi-Fi 6的路由器在2019年下半年密集上市,但价格高达两三千元。到2020年上半年,价格下降到三四百元合理区间,并且选择越来越多样化。消费者想要体验新Wi-Fi标准的高网速,付出的成本已非常低廉。 WIFI7要走入我们的生活,还有很长的路要走。 ~END~ 免责声明:本文内容由21ic获得授权后发布,版权归原作者所有,本平台仅提供信息存储服务。文章仅代表作者个人观点,不代表本平台立场,如有问题,请联系我们,谢谢!

                        时间:2020-11-09 关键词: 网络 射频技术

                      • 数字化,影响打工人了吗?

                        本文来源:脑极体 1996年12月,未来学家尼葛洛庞帝的《数字化生存》(Being Digital)一书在中国出版。最后这本书卖出了60万册,而中国的互联网产业也在此后开始了井喷式发展。 尼葛洛庞帝在《数字化生存》一书中,准确地预言了未来数字网络将彻底改变我们的生存方式,比特(bit)将取代原子成为我们人类生活的基本交换物。如今,我们生产、交换、消费还有消化和遗弃数字信息,一如物理世界的真实消费一样,几乎所有人都已经主动进入或被动卷入数字化的生存方式之中。 “数字化生存”的好处自然是显而易见的,我们从中享受到经济生活的福祉远胜任何一个历史时期。不过,正如“凡事都有两面性”的辩证法箴言所透露出的,我们也在遭遇“数字化生存”对我们的全面重新塑造,而同时我们也在遭遇种种的数字“异化”。 记得几个月前,看到一个非常二次元的故事。一个名为“金丹-元婴”的贴吧用户在百度艾斯吧卧底五年,各种伪装隐忍,终于上位成为这个贴吧的吧主。精彩之处就是,在上位之后一夜之间,他删光了所有关于《海贼王》的艾斯的帖子,重新将这个充斥海贼迷的贴吧“复辟”为《奥特曼》中艾斯·奥特曼的粉丝吧。 这位艾斯·奥特曼吧的吧主,可谓是真正实践了所谓的“数字化生存”,他在这五年当中所投入的时间、精力和长期的隐忍策略,都足以说明他已经成为数字世界的标准原住民。但是这种数字化生存是否已经有一种“异化”的成分,值得我们警惕。 从快手厕所计时器说起, 职场人的“数字化生存”困局 快手公司的这张厕所计时图注定会成为标注数字时代的一个缩影。在继996.ICU、“社畜”之后,“打工人”成为2020年的新热词,而我们见证了职场人生存空间的又一场“溃败”。 快手的本意可能是为了解决办公楼里“人多坑少”的矛盾,提醒占坑的同事不要过长时间的占用宝贵的如厕资源。但是为如厕时间计时,还要让排队的人群看到这一信息,通过内外施压的方式来监督里面的人,实在是有点太不地道了。多少职场人将茶水间、厕所当作放松的最后一点私人空间,终究还是失守了。 看过有关富士康等流水线工厂报道的人就会知道,这些产业工人早已在现代化严密的工作制度下把一切行为进行了标准化管理,其中一条就是把上厕所时间给压榨到几分几秒。不曾想,用在流水线工人身上的方法也在向依靠出卖脑力资源的白领身上了。 现代产业工人的生存方式大多要归功于弗雷德里克·泰勒这位科学管理之父,他的《科学管理原理》成为现代化生产的扛鼎之作,也是他一手参与了福特的第一条汽车流水生产线的创建。对于工人而言,受益之处就在于知道一天干多少活,该拿多少工资,劳动生产效率大幅提升,其代价就是工人们只能按照固定工种和标准规范去进行工作就行,一如卓别林大师《摩登时代》里表现的那样。 现在,这套用于产业流水线工人的方法却正在应用到要发挥人们的创造力和脑力资源的现代企业管理上,而且企业家们有了更加得心应手的数字化工具——一些用于监控和分析员工工作行为的管理软件及其算法。 在今年疫情中,美国一家提供办公系统监控软件的公司的业务咨询量提高了三倍,有三分之一的客户选择订购了这一服务。这套软件可以让上司领导来直接监控员工的电脑桌面,并可以对电脑屏幕进行录屏。系统软件还能对电脑各项任务所花费的时间进行记录,并对员工的工作效率进行打分。 根据《华尔街日报》的一份报道,微软就在用自己的Office365服务来收集员工跟客户之间聊天、发邮件和开会的频率,甚至是员工日历上的日程,然后微软会对这些数据进行分析,来评估员工的工作效率或者管理的成效。现在,微软在考虑将这套分析软件出售给其他企业。 在企业遭遇生存困境的时候,企业家想通过提高员工工作效率,减少人力成本的方式来拯救企业自然是无可厚非,不过在以灵活性和创造性为目标的现代企业环境中引入这种“智能监控”的方法不知道是否可以奏效? 对于职场人,原本我们以为新通讯工具和新办公软件的加入是帮助我们减轻劳动强度,提高劳动效率,但现在反过来成了随时找到、监控和分析我们的“主人”。 哪里有压迫,哪里就有反抗。“打工人”既可以用一套“打工人语录”来自嘲,也可以发明出“摸鱼学”来应付了事。尽管我们想尽办法逃避这套职场数字“异化”管理,但也大概率逃不出自己手中的那个数字“异化”生存。 现实版《黑镜》: 消费主义时代的买单人 最近看到一则新闻非常让人气愤。成都一个外卖小哥在送餐时被下单人打成了颅脑损伤。原因竟然是这个下单人标注要求只能敲门不要打电话,但是他又没有标注门牌号,结果外卖小哥还是打了电话确认,最终这个人恼羞成怒开始施暴。 是什么给了他这样的“勇气”打人,又是什么让他能如此暴戾?当然,除了个人的无知和精神情绪问题外,我想还有一个重要原因就是,在线服务平台带给人们的一种生存错觉,他“理所当然”地认为自己理应享受到如期所愿的服务。尽管这个打人者的反应着实让人吃惊,但他的行为确实反应出一个现象,就是在数字化生存的高精度和高效率之下,我们现代人的容错率和耐心一再下降。我们对开车等红灯、叫车等车、吃饭排队等要求越来越准确,而对系统出错或者无法融入这个系统的人越发没有耐心。而这恰好正是我们被数字“异化”的另一个表现,我们正在嵌套进入数字服务的一个链条当中。 造成这种数字“异化”生存的根源,就来自于我们日渐沉迷的“数字世界”。2020年Netflix的高分纪录片《监视资本主义:智能陷阱》中,揭示了一个正在发生的可怕趋势,社交媒体的泛滥造成青少年抑郁症患病率的直线上升。显然,社交媒体带给我们极大的社交便利,即时新闻推送给了我们快捷的资讯信息,小视频和直播平台带给我们及时满足的欢愉和精神享受。 但与此同时,这些数字工具也剥夺了我们建立深度社交、深度思考和学习以及延迟满足精神需要的可能。现在,我们被滤镜、刻意的剪辑、充满套路的修辞、蒙太奇的表现、情绪化的表演、充分情绪的评论和层出不穷的新鲜创意的包围,大脑每日都在享受着日渐成瘾的高频刺激。 这正是我们在享受智能化工具时不得不付出的代价。正如英剧《黑镜》中有一集所展示的,白人女主因为大数据系统分析如何才能出名,被劝说从歌手转型为艳星,而黑人男主要用自杀来反抗这个无处不在的数字消费帝国,却被当作脱口秀演员来为大众提供另类表演。无论如何反抗,都不能逃出数字娱乐产业的魔咒。 对于互联网时代的原住民,一如开头提到的身居贴吧的那个隐忍吧主,他们既是这场数字化生存的最早成瘾者,也可能是这场数字化生存的最早免疫者。未来他们将决定我们的数字化世界是否向更加泛滥而无所不至的地步进化,造就下一个“娱乐至死”的新时代? 毕竟,当前这些互联网应用平台的主要开发者都是这些20-30岁左右的年轻人,而那些更年长者,要么已经跻身管理者阶层,结成利益共同体,要从这些平台中攫取高额利益,要么大部分人成为这场数字化生存的忠实消费者。 这其中,包括我们大部分人,以及我们的长辈和孩子。 数字“异化”的两面: 一面抛弃一面压榨 数字“异化”生存,也并不是以单一面向示人,它还有另外一个面向的残酷,那就是是对于那些无法活在数字世界当中的人群的“惩罚”。一如疫情期间,没有智能手机,更不能出示防疫二维码的老年人,硬生生被司机和乘客从公交车上赶下去,也如前几天,不会使用微信预约的老年人在医院里大喊“你们不能把老年人绝之门外”的痛苦。 尽管这些缺乏人性化的举措都很快得到了整改,但是这一现象无不揭示出一种冷峻的现实:如果无法完成数字化的嵌入,未来我们将寸步难行。 而完成“数字化嵌入”,也很容易,只需要给你一部智能手机就可以。我们注意到只要子女们为长辈下载完相关应用,开通了账户之后,这些中老年人也很快会沉浸其中,无论是操心各种家国大事、八卦轶事,还是沉浸在各种鸡汤短视频当中,他们也大多没有任何抵抗,就被这些数字产品所绑定。 从根本上来说,任何人在信息成瘾和大脑的瞬时奖励机制上,都没有多少抵抗力。但是相比于久经考验的年轻人,老年人可能更加毫无经验。比如最近曝出的中年阿姨在抖音上被假冒某位男明星的账号所欺骗。面对这些大多数人一眼就能认出的骗子账号,沉浸其中的阿姨却难以从这套原本非常拙劣的骗术中清醒过来。 可以想见,如此众多的生活在原本狭小生活经验中的中老年人,突然遭遇一个光怪陆离的数字化世界,他们被收割的将不仅仅是时间、注意力,甚至是情感和原本就不宽裕的积蓄。而对于那些娴熟利用数字平台规则、熟悉套路玩法的人们,将成为这场新涌入流量的收割者。 对于这场已然汹涌而至的数字化世界,我们其实根本还未做好准备,就已经入局并随波逐流。我们无疑是这场数字化生存的受益者,但同时我们又是这场数字化生存的受害者。 这种体验是随着年龄的增长而增加,特别是当你有了孩子,看到自己的孩子对着随处可得的数码产品和数字内容,眼睛一眨不眨地投入其中,被那些扁平化的内容吸引到呵呵傻笑的时候,这种对于数字“异化”的体验则更加深刻。 现在我们生存在一个更加巨大的数字“异化”的生存危机当中,也许我们和我们下一代斗争的结果只能是“常常不满,偶尔成功,总是失败”,但是我们也必须要开始一场针对数字“异化”生存的严肃拷问了。 ~END~ 免责声明:本文内容由21ic获得授权后发布,版权归原作者所有,本平台仅提供信息存储服务。文章仅代表作者个人观点,不代表本平台立场,如有问题,请联系我们,谢谢!

                        时间:2020-11-09 关键词: 互联网 AI

                      • 是否患有新冠肺炎? 你咳嗽一声

                        日前在医学与生物工程杂志(IEEE Open Journal of Engineering in Medicine and Biology)有一篇预发布研究论文:COVID-19 Artificial Intelligence Diagnosis using only Cough Recordings?报道了麻省理工学院(MIT)研究团队利用AI开发了一种无症状感染检测新方法。该方法检测你是否患有新冠病毒,只需要你咳嗽一声。 论文网址: https://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&arnumber=9208795 基于人工神经网络算法,在他们自行建立的迄今为止最大的咳嗽数据集测试,对于无症状感染者的诊断准确率可达到100%。 MIT研究团队已经与一家企业展开合作,计划将该AI算法整合到手机应用程序中。项目负责人布莱恩·苏比拉纳(Brian Subirana)表示: 如果每个人在去教室,工厂或餐厅之前都使用该AI诊断工具,将会有效减少新冠大流行的传播。” ▲ 论文简介 为了提高新冠肺炎检测的准确率,需要选择好的AI模型以及搜集用于训练模型的大量数据。为此,从今年4月MIM研究人员就建立了一个公开的咳嗽手机网站。允许所有人通过网络浏览器、手机或者笔记本电脑等设备自愿提交咳嗽录音。 ▲ MIT收集咳嗽网站 网站地址:https://opensigma.mit.edu/ 截止测试前,该网站收集了超过7万个录音,每段录音中有几次咳嗽,约有20万份咳嗽音频样本。其中,2500多个样本是由已经确诊患者提交的,包括那些无症状感染者。 Subirana称:“在医疗领域,这是迄今为止最大的咳嗽数据集”。 ▲ 调查问卷 在选择合适的AI模型上,MIT研究团队利用了他们在利用声音辨别阿川兹海默症(AD)早期患者的经验,设计了一个集成有三个模型的神经网络结构。下图来自他们论文中的对于网络结构的示意图,其中酱红色部分显示了三个神经网络模型组成。 ▲ 新冠病毒AI检测模型结构 第一个神经网络代表一个人声带的强弱,利用有声读物数据集(含1000h语音)进行训练; 第二神经网络用来区分言语中的情绪状态。据了解,AD患者的神经功能衰退较一般人更为普遍,经常会表现出沮丧、悲伤等负面情绪。因此,研究人员利用演员表达不同情绪的大型语音数据集,开发了情绪语音分类器。 第三个神经网络在自建的咳嗽数据集上训练,用来辨别肺和呼吸功能的变化。 ▲ 实验数据结果 最后将三种模型结合起来,形成了一个用于检测肌肉退化的AI框架。研究人员经过检测发现,基于声带强度、情绪、肺和呼吸功能等生物特征,基于该模型来诊断COVID-19。 ▲ 模型检测ROC指标 需要强调的是,该AI模型的优势不在于检测有症状的新冠患者。 这一点Subirana在论文中也明确强调。他说,不管他们的症状是由COVID-19还是其他症状(如流感或哮喘)引起的。该工具的优势在于它能够分辨无症状感染者的咳嗽和健康人的咳嗽。 看完他们的文章,我还专门到他们的数据搜集检测网站咳嗽了几声,测试一下自己的咳嗽声音,谁知…... 公众号留言 老师您好,今天突然回头调试去年的电磁车,发现有个问题。在去年比赛时候c车舵机内置磁场对5cm电感采值影响很大,询问一下中南大学他们是直接修改了机械结构,其他方法不从得知,您可不可以做一期关于这方面的文章,关于如何降低舵机磁场对短前瞻的影响? 回复:可以到csdn网站搜索:“电磁信号检测 | 本是同根生,相煎何太急”查看以前讨论如何防止电磁检测干扰问题。 免责声明:本文内容由21ic获得授权后发布,版权归原作者所有,本平台仅提供信息存储服务。文章仅代表作者个人观点,不代表本平台立场,如有问题,请联系我们,谢谢!

                        时间:2020-11-09 关键词: AI 电子医疗

                      首页  上一页  1 2 3 4 5 6 7 8 9 10 下一页 尾页
                      发布文章
                      亚洲 日韩 国产 有码 不卡