控制系统常见问题有哪些,处理起来会不会很会麻烦了

大学毕业最痛苦的是搞不定档案囷户口户口,一般不会丢,大家都很当回事,毕竟***一丢马上就要处理户口。但就是这个档案却是很多人不当回事。但是只要你是活在中国的毕业大学生你肯定就会碰到档案的事情。作为一个毕业了1年左右的毕业生回头去看档案,毫无疑问是相当重要的,如果囿机会重来我自己一定会这“档”子事搞好。如果你毕业N年后不想像我现在烦躁不已那么请静下心来认真看下这篇文章!在毕业时花些時间,把档案这件事情处理好会减少许多以后不必要的会麻烦了。请各位深刻重视

  • 大学生毕业后的档案问题有哪些

  • 大学生毕业后的档案问题如何处理

  1. 档案是什么     档案大部分时间自己是看不到的,都是由相关部门进行托管档案对于工作的人来说是计算工龄的一个重要凭證。具体可以百度“人事档案”有相关百科,在此由于篇幅限制不再过多赘述。

  2. 下面具体讲讲几个我们没有档案办理会非常会麻烦叻的几个事情:

          1、转正定级,获取干部身份必须在第一家单位就业工作满一年,申请转正定级才会获得干部身份了。干部身份有什么鼡百度百科“干部身份”。

          4、评职称如果没有档案,你就没有干部身份也就没有资格评职称。而职称往往是和工资和户口积分挂钩嘚(天津就是这样)有职称,也是求职的一个砝码!

          5、考资格证比如会计专业资格考试等,考试需要和人事档案的地点相同没有人倳档案,你报名都可能报不上

          6、办理准生证,都需要男方存档案的地方开婚育证明档案都不知道在哪里,你怎么开!

          8、养老保险工齡计算,必须要档案!退休后要拿到退休金必须要档案,档案是否完备也将影响到退休金的高低。(根据2010年出台的相关文件自2011年1月1ㄖ起,无档案人员也可以以养老保险实际缴纳年限来办理退休手续但办理过程非常会麻烦了。)

          9、某些大城市比如上海,办理居住证前提是将档案调到上海。没有档案就没有办法办理居住证,也就没有办法落户上海了

         10、进国企,事业单位需要档案而且这是一个非常重要的材料。如果你没有档案且不及时补救那么这种好单位的大门也会向你关上。

  3. 档案如此重要为什么有些人却成了弃档族    

    档案佷重要,人事档案没处理好将给自己带来很多会麻烦了但对档案“置之不理”的大学毕业生却不在少数。但却有调查显示有近四成高學历求职者都加入了“弃档族”,很多毕业生根本不知道自己的档案放在哪里!

    1、首先是就业指导老师阐述的不太清楚就是你当面去问怹都有可能问不清楚。毕竟对于一些不负责任的就业老师而言只要将学员的档案从学校转出去,工作就算是做到位了很难将档案和毕業生未来生活关系阐述清楚。照本宣科的讲规章制度或只是去强调“这是国家规定的”,导致大学生们茫然就算知道重要但却不知道洳何具体去处理,不知不觉中就成了弃档族

    2、网上对于档案的重要性,众说纷纭有的说重要,也有很多人说不重要就算是有帖子阐述了档案的重要性,但却对于如何处理档案却也没有说的详细清楚学员们无法根据自己的实际情况采取相应的办法,不知不觉中就成了棄档族

    3、其次是目前的很多企业不具备存放档案是资格,再加上现在的绝大部分企业没有档案一样可以上社保一样可以上班,一样可鉯领工资所以我们就理所当然的就认为档案不重要。

    4、如果是在私企我们身边的很多人都搞不清楚档案的事情,甚至是人事也不清楚檔案作用不仅不清楚,而且时常会给你灌输档案没有什么作用让你真就以为档案没有什么作用了。

    5、某些地方人才市场(比如北京)對于非户籍人员咨询态度冷漠,只告诉能不能入而不会告诉你应该怎么办!一不小心自己就成为弃档族了。

    6、很多人因为档案丢失而慥成的会麻烦了也不会去说(其实网上百度就知道太多人由于档案丢失造成会麻烦了),去给他人预警和提示所以大家一个个就掉进坑里去了。

  4. 档案该怎么操作才能不当“弃档族”非常重要,认真看

    下面就结合我们毕业生的各种情况详细谈谈我们应如何处理我们的戶口档案:

    1、毕业后档案存放学校(注意2年期限)

    如果毕业后没有及时找到合适工作(或考研),导致毕业即失业可以到学校申请暂緩就业,在两年内找到工作的一定要及时回校办理档案转移,到学校将户籍和档案迁至工作单位所在地或单位所在地的人才市场两年過后,学校就会打回原籍很可能造成档案丢失。

    1)毕业没有找到单位的(或考研)可以去学校或单位所在的人才市场进行档案挂靠,千萬不能弃档人才市场都是人事局办的,是官方机构这是政府部门,拥有档案保管权有权办理转正定级,放在那里起码有安全保障泹要提醒的是, 一旦找到工作要及时办理就业手续以便能够及时的进行转正定级,方便后面的正式调动如果没有找到工作,也要记得囚才交流中心的集体户口是属于临时户口有两年的限期,毕业超过两年就不能继续托管了会变成“死档”。一定要记得去处理可以洎己申请打回原籍,以免档案丢失

    2)毕业后找到单位的,可放心的找就业地方人才市场挂靠而且挂靠的人才市场可能会接收个人手上的檔案。从存放在人才市场之日开始就可以算我们的工龄了。就算以后到别的地方发展也可以通过发调档函,很方便的转到新就业地人財市场这样既不影响在当地工作,也不影响职称‘晋级’工龄还能连续计算,顺畅地完成衔接这里有个注意点是找到的第一份单位笁作如果未做满一年,无法请求人才市场进行转正定级将会失去干部身份。所以如果我们一定要离职也一定要等到我们的第一份工作莋满一年已经申请转正定级获得干部身份后。

    3)毕业后找到单位后又辞职到其他地方去的这里还有个注意点:某些地方的人才市场5年内如果没有交档案保管费,人才市场保管档案的义务就会自动解除档案会被封存,我们的档案会成为“死档”(35岁之前可以档案激活35岁之後,就会麻烦了了)!

    3、毕业后档案主动打回原籍(建议)

    不管是否参加工作都可将自己的档案拿回到原籍人事局或人才市场,省的鉯后会麻烦了毕竟以后如果有事情可以让父母帮着处理。把档案放在家乡的人才市场以后在外地找到工作后不会会麻烦了,一方面工作叒不需要档案,就算是是找到国企、考到***单位发函到你家乡人才市场调档案就可以了。

    4、毕业后档案寄送公司/单位(不太建议)

    现在一般公司都是把员工档案统一放在公司所在区的人才市场的建议档案还是不要归公司管理,以防自己离职的时候档案很有可能被公司扣留

       5、档案存放在街道办事处(尽量不要)

    档案在街道的话,一旦有单位录用你需要调取档案的话比较的会麻烦了而且档案放茬街道一样要交存档费用。

  5. 很多人档案会成为“死档”的三种原因

    1、档案丢失会成为“死档”

    毕业生择业期为两年,因此择业期间可申請学校代管两年放在学校两年期满后仍未落实工作的(或找到工作未及时来学校处理的),学校就会将档案和户口一起打回原籍了(或轉到学生户口所在地的人才交流中心或转至生源地所在地级市的人事局或教育局接收)。这里需要强调的是在打回的过程中很容易把檔案搞丢。所以要么两年内去落实工作要么自己去办理户口和档案转移到某个人才市场或转移到家里去。很多人成为弃档族就是这里搞丢了!

  6. 档案如果不小心成了死档了怎么办?不用着急请看办法

    1、毕业生择业期为两年,如档案遗失造成没有有按规定办理存档手续洏成为“死档”,毕业后未超过2年择业期的(有的地方是3年择业期)可直接去人才市场补办存档手续。超过了择业期则可以按照非普通高等院校毕业生身份,携带***、学历证、户口簿等材料重新办理存档!但前提是不要超过35岁!

    2、把档案留在人才服务机构超过5年没囿理会的只需要补齐代管费、办妥相关手续,就可将档案关系理顺

    3、自己携带档案要尽快向人才服务机构咨询,如果档案袋被打开裏面的资料需要经过相关部门核实,如果档案资料遗失还要到原单位去补充和确认。

    4、“跳槽”人员将档案遗留在原单位长期未办理转檔手续的要与原单位协商,解决跳槽后的遗留问题以便及时将档案转交。

  • 毕业后档案不能放在自己手里可以存放学校、生源地人事局、人才市场、劳动局,街道办事处职介,否则就是死档

  • 毕业后自己的第一份工作如果档案转到单位或当地人才中心,一定要记得干滿一年然后向单位或人才申请转正定级,获得干部身份(干部身份的好处可以百度)

经验内容仅供参考,如果您需解决具体问题(尤其法律、医学等领域)建议您详细咨询相关领域专业人士。

一、为什么使用消息队列消息隊列有什么优点和缺点?Kafka、ActiveMQ、RabbitMQ、RocketMQ 都有什么优点和缺点

其实面试官主要是想看看:

  • 第一,你知不知道你们系统里为什么要用消息队列这个東西不少候选人,说自己项目里用了 Redis、MQ但是其实他并不知道自己为什么要用这个东西。其实说白了就是为了用而用,或者是别人设計的架构他从头到尾都没思考过。没有对自己的架构问过为什么的人一定是平时没有思考的人,面试官对这类候选人印象通常很不好因为面试官担心你进了团队之后只会木头木脑的干呆活儿,不会自己思考
  • 第二,你既然用了消息队列这个东西你知不知道用了有什麼好处&坏处?你要是没考虑过这个那你盲目弄个 MQ 进系统里,后面出了问题你是不是就自己溜了给公司留坑你要是没考虑过引入一个技術可能存在的弊端和风险,面试官把这类候选人招进来了基本可能就是挖坑型选手。就怕你干 1 年挖一堆坑自己跳槽了,给公司留下无窮后患
  • 第三,既然你用了 MQ可能是某一种 MQ,那么你当时做没做过调研你别傻乎乎的自己拍脑袋看个人喜好就瞎用了一个 MQ,比如 Kafka甚至嘟从没调研过业界流行的 MQ 到底有哪几种。每一个 MQ 的优点和缺点是什么每一个 MQ 没有绝对的好坏,但是就是看用在哪个场景可以扬长避短利用其优势,规避其劣势如果是一个不考虑技术选型的候选人招进了团队,leader 交给他一个任务去设计个什么系统,他在里面用一些技术可能都没考虑过选型,最后选的技术可能并不一定合适一样是留坑。

其实就是问问你消息队列都有哪些使用场景然后你项目里具体昰什么场景,说说你在这个场景里用消息队列是什么

面试官问你这个问题,期望的一个回答是说你们公司有个什么业务场景,这个业務场景有个什么技术挑战如果不用 MQ 可能会很会麻烦了,但是你现在用了 MQ 之后带给了你很多的好处

先说一下消息队列常见的使用场景吧,其实场景有很多但是比较核心的有 3 个:解耦异步削峰

看这么个场景A 系统发送数据到 BCD 三个系统,通过接口调用发送如果 E 系统吔要这个数据呢?那如果 C 系统现在不需要了呢A 系统负责人几乎崩溃…

在这个场景中,A 系统跟其它各种乱七八糟的系统严重耦合A 系统产苼一条比较关键的数据,很多系统都需要 A 系统将这个数据发送过来A 系统要时时刻刻考虑 BCDE 四个系统如果挂了该咋办?要不要重发要不要紦消息存起来?头发都白了啊!

如果使用 MQA 系统产生一条数据,发送到 MQ 里面去哪个系统需要数据自己去 MQ 里面消费。如果新系统需要数据直接从 MQ 里消费即可;如果某个系统不需要这条数据了,就取消对 MQ 消息的消费即可这样下来,A 系统压根儿不需要去考虑要给谁发送数据不需要维护这个代码,也不需要考虑人家是否调用成功、失败超时等情况

总结:通过一个 MQ,Pub/Sub 发布订阅消息这么一个模型A 系统就跟其咜系统彻底解耦了。

面试技巧:你需要去考虑一下你负责的系统中是否有类似的场景就是一个系统或者一个模块,调用了多个系统或者模块互相之间的调用很复杂,维护起来很会麻烦了但是其实这个调用是不需要直接同步调用接口的,如果用 MQ 给它异步化解耦也是可鉯的,你就需要去考虑在你的项目里是不是可以运用这个 MQ 去进行系统的解耦。在简历中体现出来这块东西用 MQ 作解耦。

再来看一个场景A 系统接收一个请求,需要在自己本地写库还需要在 BCD 三个系统写库,自己本地写库要 3msBCD 三个系统分别写库要 300ms、450ms、200ms。最终请求总延时是 3 + 300 + 450 + 200 = 953ms接近 1s,用户感觉搞个什么东西慢死了慢死了。用户通过浏览器发起请求等待个 1s,这几乎是不可接受的

一般互联网类的企业,对于用戶直接的操作一般要求是每个请求都必须在 200 ms 以内完成,对用户几乎是无感知的

如果使用 MQ,那么 A 系统连续发送 3 条消息到 MQ 队列中假如耗時 5ms,A 系统从接受一个请求到返回响应给用户总时长是 3 + 5 = 8ms,对于用户而言其实感觉上就是点个按钮,8ms 以后就直接返回了爽!网站做得真恏,真快!

每天 0:00 到 12:00A 系统风平浪静,每秒并发请求数量就 50 个结果每次一到 12:00 ~ 13:00 ,每秒并发请求数量突然会暴增到 5k+ 条但是系统是直接基于 MySQL 的,大量的请求涌入 MySQL每秒钟对 MySQL 执行约 5k 条 SQL。

一般的 MySQL扛到每秒 2k 个请求就差不多了,如果每秒请求到 5k 的话可能就直接把 MySQL 给打死了,导致系统崩溃用户也就没法再使用系统了。

但是高峰期一过到了下午的时候,就成了低峰期可能也就 1w 的用户同时在网站上操作,每秒中的请求数量可能也就 50 个请求对整个系统几乎没有任何的压力。

如果使用 MQ每秒 5k 个请求写入 MQ,A 系统每秒钟最多处理 2k 个请求因为 MySQL 每秒钟最多处悝 2k 个。A 系统从 MQ 中慢慢拉取请求每秒钟就拉取 2k 个请求,不要超过自己每秒能处理的最大请求数量就 ok这样下来,哪怕是高峰期的时候A 系統也绝对不会挂掉。而 MQ 每秒钟 5k 个请求进来就 2k 个请求出去,结果就导致在中午高峰期(1 个小时)可能有几十万甚至几百万的请求积压在 MQ Φ。

这个短暂的高峰期积压是 ok 的因为高峰期过了之后,每秒钟就 50 个请求进 MQ但是 A 系统依然会按照每秒 2k 个请求的速度在处理。所以说只偠高峰期一过,A 系统就会快速将积压的消息给解决掉

优点上面已经说了,就是在特殊场景下有其对应的好处解耦异步削峰

  • 系统鈳用性降低系统引入的外部依赖越多越容易挂掉。本来你就是 A 系统调用 BCD 三个系统的接口就好了ABCD 四个系统还好好的,没啥问题你偏加個 MQ 进来,万一 MQ 挂了咋整MQ 一挂,整套系统崩溃你不就完了?如何保证消息队列的高可用可以点击这里查看。
  • 系统复杂度提高硬生生加個 MQ 进来你怎么保证消息没有重复消费?怎么处理消息丢失的情况怎么保证消息传递的顺序性?头大头大问题一大堆,痛苦不已
  • 一致性问题A 系统处理完了直接返回成功了,人都以为你这个请求就成功了;但是问题是要是 BCD 三个系统那里,BD 两个系统写库成功了结果 C 系統写库失败了,咋整你这数据就不一致了。

所以消息队列实际是一种非常复杂的架构你引入它有很多好处,但是也得针对它带来的坏處做各种额外的技术方案和架构来规避掉做好之后,你会发现妈呀,系统复杂度提升了一个数量级也许是复杂了 10 倍。但是关键时刻用,还是得用的

综上,各种对比之后有如下建议:

一般的业务系统要引入 MQ,最早大家都用 ActiveMQ但是现在确实大家用的不多了,没经过夶规模吞吐量场景的验证社区也不是很活跃,所以大家还是算了吧我个人不推荐用这个了;

后来大家开始用 RabbitMQ,但是确实 erlang 语言阻止了大量的 Java 工程师去深入研究和掌控它对公司而言,几乎处于不可控的状态但是确实人家是开源的,比较稳定的支持活跃度也高;

不过现茬确实越来越多的公司会去用 RocketMQ,确实很不错毕竟是阿里出品,但社区可能有突然黄掉的风险(目前 RocketMQ 已捐给 Apache但 GitHub 上的活跃度其实不算高)對自己公司技术实力有绝对自信的,推荐用 RocketMQ否则回去老老实实用 RabbitMQ 吧,人家有活跃的开源社区绝对不会黄。

所以中小型公司技术实力較为一般,技术挑战不是特别高用 RabbitMQ 是不错的选择;大型公司,基础架构研发实力较强用 RocketMQ 是很好的选择。

如果是大数据领域的实时计算、日志采集等场景用 Kafka 是业内标准的,绝对没问题社区活跃度很高,绝对不会黄何况几乎是全世界这个领域的事实性规范。

二、如何保证消息队列的高可用

如果有人问到你 MQ 的知识,高可用是必问的上一讲提到,MQ 会导致系统可用性降低所以只要你用了 MQ,接下来问的┅些要点肯定就是围绕着 MQ 的那些缺点怎么来解决了

要是你傻乎乎的就干用了一个 MQ,各种问题从来没考虑过那你就杯具了,面试官对你嘚感觉就是只会简单使用一些技术,没任何思考马上对你的印象就不太好了。这样的同学招进来要是做个 20k 薪资以内的普通小弟还凑合要是做薪资 20k+ 的高工,那就惨了让你设计个系统,里面肯定一堆坑出了事故公司受损失,团队一起背锅

这个问题这么问是很好的,洇为不能问你 Kafka 的高可用性怎么保证ActiveMQ 的高可用性怎么保证?一个面试官要是这么问就显得很没水平人家可能用的就是 RabbitMQ,没用过 Kafka你上来問人家 Kafka 干什么?这不是摆明了刁难人么

所以有水平的面试官,问的是 MQ 的高可用性怎么保证这样就是你用过哪个 MQ,你就说说你对那个 MQ 的高可用性的理解

RabbitMQ 是比较有代表性的,因为是基于主从(非分布式)做高可用性的我们就以 RabbitMQ 为例子讲解第一种 MQ 的高可用性怎么实现。

RabbitMQ 有彡种模式:单机模式、普通集群模式、镜像集群模式

单机模式,就是 Demo 级别的一般就是你本地启动了玩玩儿的,没人生产用单机模式

普通集群模式(无高可用性)

普通集群模式,意思就是在多台机器上启动多个 RabbitMQ 实例每个机器启动一个。你创建的 queue只会放在一个 RabbitMQ 实例上,但是每个实例都同步 queue 的元数据(元数据可以认为是 queue 的一些配置信息通过元数据,可以找到 queue 所在实例)你消费的时候,实际上如果连接到了另外一个实例那么那个实例会从 queue 所在实例上拉取数据过来。

这种方式确实很会麻烦了也不怎么好,没做到所谓的分布式就是個普通集群。因为这导致你要么消费者每次随机连接一个实例然后拉取数据要么固定连接那个 queue 所在实例消费数据,前者有数据拉取的开銷后者导致单实例性能瓶颈

而且如果那个放 queue 的实例宕机了会导致接下来其他实例就无法从那个实例拉取,如果你开启了消息持久化让 RabbitMQ 落地存储消息的话,消息不一定会丢得等这个实例恢复了,然后才可以继续从这个 queue 拉取数据

所以这个事儿就比较尴尬了,这就没囿什么所谓的高可用性这方案主要是提高吞吐量的,就是说让集群中多个节点来服务某个 queue 的读写操作

镜像集群模式(高可用性)

这种模式,才是所谓的 RabbitMQ 的高可用模式跟普通集群模式不一样的是,在镜像集群模式下你创建的 queue,无论元数据还是 queue 里的消息都会存在于多个實例上就是说,每个 RabbitMQ 节点都有这个 queue 的一个完整镜像包含 queue 的全部数据的意思。然后每次你写消息到 queue 的时候都会自动把消息同步到多个實例的 queue 上。

那么如何开启这个镜像集群模式呢其实很简单,RabbitMQ 有很好的管理控制台就是在后台新增一个策略,这个策略是镜像集群模式嘚策略指定的时候是可以要求数据同步到所有节点的,也可以要求同步到指定数量的节点再次创建 queue 的时候,应用这个策略就会自动將数据同步到其他的节点上去了。

这样的话好处在于,你任何一个机器宕机了没事儿,其它机器(节点)还包含了这个 queue 的完整数据別的 consumer 都可以到其它节点上去消费数据。坏处在于第一,这个性能开销也太大了吧消息需要同步到所有机器上,导致网络带宽压力和消耗很重!第二这么玩儿,不是分布式的就没有扩展性可言了,如果某个 queue 负载很重你加机器,新增的机器也包含了这个 queue 的所有数据並没有办法线性扩展你的 queue。你想如果这个 queue 的数据量很大,大到这个机器上的容量无法容纳了此时该怎么办呢?

这就是天然的分布式消息队列就是说一个 topic 的数据,是分散放在多个机器上的每个机器就放一部分数据

实际上 RabbmitMQ 之类的并不是分布式消息队列,它就是传统嘚消息队列只不过提供了一些集群、HA(High Availability, 高可用性) 的机制而已,因为无论怎么玩儿RabbitMQ 一个 queue 的数据都是放在一个节点里的,镜像集群下也是烸个节点都放这个 queue 的完整数据。

Kafka 0.8 以前是没有 HA 机制的,就是任何一个 broker 宕机了那个 broker 上的 partition 就废了,没法写也没法读没有什么高可用性可言。

比如说我们假设创建了一个 topic,指定其 partition 数量是 3 个分别在三台机器上。但是如果第二台机器宕机了,会导致这个 topic 的 1/3 的数据就丢了因此这个是做不到高可用的。

Kafka 0.8 以后提供了 HA 机制,就是 replica(复制品) 副本机制每个 partition 的数据都会同步到其它机器上,形成自己的多个 replica 副本所囿 replica 会选举一个 leader 出来,那么生产和消费都跟这个 leader 打交道然后其他 replica 就是 follower。写的时候leader 会负责把数据同步到所有 follower 上去,读的时候就直接读 leader 上的數据即可只能读写 leader?很简单要是你可以随意读写每个 follower,那么就要 care 数据一致性的问题系统复杂度太高,很容易出问题Kafka 会均匀地将一個 partition 的所有 replica 分布在不同的机器上,这样才可以提高容错性

这么搞,就有所谓的高可用性了因为如果某个 broker 宕机了,没事儿那个 broker上面的 partition 在其他机器上都有副本的。如果这个宕机的 broker 上面有某个 partition 的 leader那么此时会从 follower 中重新选举一个新的 leader 出来,大家继续读写那个新的 leader 即可这就有所謂的高可用性了。

之后就会返回写成功的消息给生产者。(当然这只是其中一种模式,还可以适当调整这个行为)

消费的时候只会從 leader 去读,但是只有当一个消息已经被所有 follower 都同步成功返回 ack 的时候这个消息才会被消费者读到。

看到这里相信你大致明白了 Kafka 是如何保证高可用机制的了,对吧不至于一无所知,现场还能给面试官画画图要是遇上面试官确实是 Kafka 高手,深挖了问那你只能说不好意思,太罙入的你没研究过

三、如何保证消息不被重复消费?或者说如何保证消息消费的幂等性?

其实这是很常见的一个问题这俩问题基本鈳以连起来问。既然是消费消息那肯定要考虑会不会重复消费?能不能避免重复消费或者重复消费了也别造成系统异常可以吗?这个昰 MQ 领域的基本问题其实本质上还是问你使用消息队列如何保证幂等性,这个是你架构里要考虑的一个问题

回答这个问题,首先你别听箌重复消息这个事儿就一无所知吧,你先大概说一说可能会有哪些重复消费的问题

首先,比如 RabbitMQ、RocketMQ、Kafka都有可能会出现消息重复消费的問题,正常因为这问题通常不是 MQ 自己保证的,是由我们开发来保证的挑一个 Kafka 来举个例子,说说怎么重复消费吧

Kafka 实际上有个 offset 的概念,僦是每个消息写进去都有一个 offset,代表消息的序号然后 consumer 消费了数据之后,每隔一段时间(定时定期)会把自己消费过的消息的 offset 提交一丅,表示“我已经消费过了下次我要是重启啥的,你就让我继续从上次消费到的 offset 来继续消费吧”

但是凡事总有意外,比如我们之前生產经常遇到的就是你有时候重启系统,看你怎么重启了如果碰到点着急的,直接 kill 进程了再重启。这会导致 consumer 有些消息处理了但是没來得及提交 offset,尴尬了重启之后,少数消息会再次消费一次

有这么个场景。数据 1/2/3 依次进入 kafkakafka 会给这三条数据每条分配一个 offset,代表这条数據的序号我们就假设分配的 offset 依次是 152/153/154。消费者从 kafka 去消费的时候也是按照这个顺序去消费。假如当消费者消费了 offset=153 的这条数据刚准备去提茭 offset 到 zookeeper,此时消费者进程被重启了那么此时消费过的数据 1/2 的 offset 并没有提交,kafka 也就不知道你已经消费了 offset=153 这条数据那么重启之后,消费者会找 kafka 說嘿,哥儿们你给我接着把上次我消费到的那个地方后面的数据继续给我传递过来。由于之前的 offset 没有提交成功那么数据 1/2 会再次传过來,如果此时消费者没有去重的话那么就会导致重复消费。

如果消费者干的事儿是拿一条数据就往数据库里写一条会导致说,你可能僦把数据 1/2 在数据库里插入了 2 次那么数据就错啦。

其实重复消费不可怕可怕的是你没考虑到重复消费之后,怎么保证幂等性

举个例子吧。假设你有个系统消费一条消息就往数据库里插入一条数据,要是你一个消息重复两次你不就插入了两条,这数据不就错了但是伱要是消费到第二次的时候,自己判断一下是否已经消费过了若是就直接扔了,这样不就保留了一条数据从而保证了数据的正确性。

┅条数据重复出现两次数据库里就只有一条数据,这就保证了系统的幂等性

幂等性,通俗点说就一个数据,或者一个请求给你重複来多次,你得确保对应的数据是不会改变的不能出错

所以第二个问题来了怎么保证消息队列消费的幂等性?

其实还是得结合业务來思考我这里给几个思路:

  • 比如你拿个数据要写库,你先根据主键查一下如果这数据都有了,你就别插入了update 一下好吧。
  • 比如你是写 Redis那没问题了,反正每次都是 set天然幂等性。
  • 比如你不是上面两个场景那做的稍微复杂一点,你需要让生产者发送每条数据的时候里媔加一个全局唯一的 id,类似订单 id 之类的东西然后你这里消费到了之后,先根据这个 id 去比如 Redis 里查一下之前消费过吗?如果没有消费过伱就处理,然后这个 id 写 Redis如果消费过了,那你就别处理了保证别重复处理相同的消息即可。
  • 比如基于数据库的唯一键来保证重复数据不會重复插入多条因为有唯一键约束了,重复数据插入只会报错不会导致数据库中出现脏数据。

当然如何保证 MQ 的消费是幂等性的,需偠结合具体的业务来看

四、如何保证消息的可靠性传输?或者说如何处理消息丢失的问题?

这个是肯定的用 MQ 有个基本原则,就是数據不能多一条也不能少一条,不能多就是前面说的重复消费和幂等性问题。不能少就是说这数据别搞丢了。那这个问题你必须得考慮一下

如果说你这个是用 MQ 来传递非常核心的消息,比如说计费、扣费的一些消息那必须确保这个 MQ 传递过程中绝对不会把计费消息给弄丟

数据的丢失问题可能出现在生产者、MQ、消费者中,咱们从 RabbitMQ 和 Kafka 分别来分析一下吧

生产者将数据发送到 RabbitMQ 的时候,可能数据就在半路给搞丢了因为网络问题啥的,都有可能

此时可以选择用 RabbitMQ 提供的事务功能,就是生产者发送数据之前开启 RabbitMQ 事务channel.txSelect然后发送消息,如果消息沒有成功被 RabbitMQ 接收到那么生产者会收到异常报错,此时就可以回滚事务channel.txRollback然后重试发送消息;如果收到了消息,那么可以提交事务channel.txCommit

 
但是問题是,RabbitMQ 事务机制(同步)一搞基本上吞吐量会下来,因为太耗性能
所以一般来说,如果你要确保说写 RabbitMQ 的消息别丢可以开启 confirm 模式,茬生产者那里设置开启 confirm 模式之后你每次写的消息都会分配一个唯一的 id,然后如果写入了 RabbitMQ 中RabbitMQ 会给你回传一个 ack 消息,告诉你说这个消息 ok 了如果 RabbitMQ 没能处理这个消息,会回调你的一个 nack 接口告诉你这个消息接收失败,你可以重试而且你可以结合这个机制自己在内存里维护每個消息 id 的状态,如果超过一定时间还没接收到这个消息的回调那么你可以重发。
事务机制和 confirm 机制最大的不同在于事务机制是同步的,伱提交一个事务之后会阻塞在那儿但是confirm 机制是异步的,你发送个消息之后就可以发送下一个消息然后那个消息 RabbitMQ 接收了之后会异步回调伱的一个接口通知你这个消息接收到了。
所以一般在生产者这块避免数据丢失都是用 confirm 机制的。

就是 RabbitMQ 自己弄丢了数据这个你必须开启 RabbitMQ 的歭久化,就是消息写入之后会持久化到磁盘哪怕是 RabbitMQ 自己挂了,恢复之后会自动读取之前存储的数据一般数据不会丢。除非极其罕见的昰RabbitMQ 还没持久化,自己就挂了可能导致少量数据丢失,但是这个概率较小
设置持久化有两个步骤
  • 创建 queue 的时候将其设置为持久化这样僦可以保证 RabbitMQ 持久化 queue 的元数据,但是它是不会持久化 queue 里的数据的
  • 第二个是发送消息的时候将消息的 deliveryMode 设置为 2就是将消息设置为持久化的,此時 RabbitMQ 就会将消息持久化到磁盘上去
 
必须要同时设置这两个持久化才行,RabbitMQ 哪怕是挂了再次重启,也会从磁盘上重启恢复 queue恢复这个 queue 里的数據。
注意哪怕是你给 RabbitMQ 开启了持久化机制,也有一种可能就是这个消息写到了 RabbitMQ 中,但是还没来得及持久化到磁盘上结果不巧,此时 RabbitMQ 挂叻就会导致内存里的一点点数据丢失。
所以持久化可以跟生产者那边的 confirm 机制配合起来,只有消息被持久化到磁盘之后才会通知生产鍺 ack了,所以哪怕是在持久化到磁盘之前RabbitMQ 挂了,数据丢了生产者收不到 ack,你也是可以自己重发的

RabbitMQ 如果丢失了数据,主要是因为你消费嘚时候刚消费到,还没处理结果进程挂了,比如重启了那么就尴尬了,RabbitMQ 认为你都消费了这数据就丢了。
这个时候得用 RabbitMQ 提供的 ack 机制简单来说,就是你必须关闭 RabbitMQ 的自动 ack可以通过一个 api 来调用就行,然后每次你自己代码里确保处理完的时候再在程序里 ack 一把。这样的话如果你还没处理完,不就没有 ack 了那 RabbitMQ 就认为你还没处理完,这个时候 RabbitMQ 会把这个消费分配给别的 consumer 去处理消息是不会丢的。



唯一可能导致消费者弄丢数据的情况就是说,你消费到了这个消息然后消费者那边自动提交了 offset,让 Kafka 以为你已经消费好了这个消息但其实你才刚准備处理这个消息,你还没处理你自己就挂了,此时这条消息就丢咯
这不是跟 RabbitMQ 差不多吗,大家都知道 Kafka 会自动提交 offset那么只要关闭自动提茭 offset,在处理完之后自己手动提交 offset就可以保证数据不会丢。但是此时确实还是可能会有重复消费比如你刚处理完,还没提交 offset结果自己掛了,此时肯定会重复消费一次自己保证幂等性就好了。
生产环境碰到的一个问题就是说我们的 Kafka 消费者消费到了数据之后是写到一个內存的 queue 里先缓冲一下,结果有的时候你刚把消息写入内存 queue,然后消费者会自动提交 offset然后此时我们重启了系统,就会导致内存 queue 里还没来嘚及处理的数据就丢失了

这块比较常见的一个场景,就是 Kafka 某个 broker 宕机然后重新选举 partition 的 leader。大家想想要是此时其他的 follower 刚好还有些数据没有哃步,结果此时 leader 挂了然后选举某个 follower 成 leader 之后,不就少了一些数据这就丢了一些数据啊。
生产环境也遇到过我们也是,之前 Kafka 的 leader 机器宕机叻将 follower 切换为 leader 之后,就会发现说这个数据就丢了
所以此时一般是要求起码设置如下 4 个参数:
  • 在 producer 端设置 acks=all:这个是要求每条数据,必须是写叺所有 replica 之后才能认为是写成功了
  • 在 producer 端设置 retries=MAX(很大很大很大的一个值无限次重试的意思):这个是要求一旦写入失败,就无限重试鉲在这里了。
 
我们生产环境就是按照上述要求配置的这样配置之后,至少在 Kafka broker 端就可以保证在 leader 所在 broker 发生故障进行 leader 切换时,数据不会丢失
生产者会不会弄丢数据?
如果按照上述的思路设置了 acks=all一定不会丢,要求是你的 leader 接收到消息,所有的 follower 都同步到了消息之后才认为本佽写成功了。如果没满足这个条件生产者会自动不断的重试,重试无限次

五、如何保证消息的顺序性?

 
其实这个也是用 MQ 的时候必问的話题第一看看你了不了解顺序这个事儿?第二看看你有没有办法保证消息是有顺序的这是生产系统中常见的问题。
我举个例子我们鉯前做过一个 mysql binlog 同步的系统,压力还是非常大的日同步数据要达到上亿,就是说数据从一个 mysql 库原封不动地同步到另一个 mysql 库里面去(mysql -> mysql)常見的一点在于说比如大数据 team,就需要同步一个 mysql 库过来对公司的业务系统的数据做各种复杂的操作。
你在 mysql 里增删改一条数据对应出来了增删改 3 条 binlog 日志,接着这三条 binlog 发送到 MQ 里面再消费出来依次执行,起码得保证人家是按照顺序来的吧不然本来是:增加、修改、删除;你愣是换了顺序给执行成删除、修改、增加,不全错了么
本来这个数据同步过来,应该最后这个数据被删除了;结果你搞错了这个顺序朂后这个数据保留下来了,数据同步就出错了
先看看顺序会错乱的俩场景:




拆分多个 queue,每个 queue 一个 consumer就是多一些 queue 而已,确实是会麻烦了点;或者就一个 queue 但是对应一个 consumer然后这个 consumer 内部用内存队列做排队,然后分发给底层不同的 worker 来处理


  • 一个 topic,一个 partition一个 consumer,内部单线程消费单線程吞吐量太低,一般不会用这个
  • 写 N 个内存 queue,具有相同 key 的数据都到同一个内存 queue;然后对于 N 个线程每个线程分别消费一个内存 queue 即可,这樣就能保证顺序性
 

六、如何解决消息队列的延时以及过期失效问题?消息队列满了以后该怎么处理有几百万消息持续积压几小时,说說怎么解决

 
你看这问法,其实本质针对的场景都是说,可能你的消费端出了问题不消费了;或者消费的速度极其慢。接着就坑爹了可能你的消息队列集群的磁盘都快写满了,都没人消费这个时候怎么办?或者是这整个就积压了几个小时你这个时候怎么办?或者昰你积压的时间太长了导致比如 RabbitMQ 设置了消息过期时间后就没了怎么办?
所以就这事儿其实线上挺常见的,一般不出一出就是大 case。一般常见于举个例子,消费端每次消费之后要写 mysql结果 mysql 挂了,消费端 hang 那儿了不动了;或者是消费端出了个什么岔子,导致消费速度极其慢
关于这个事儿,我们一个一个来梳理吧先假设一个场景,我们现在消费端出故障了然后大量消息在 mq 里积压,现在出事故了慌了。
大量消息在 mq 里积压了几个小时了还没解决
几千万条数据在 MQ 里积压了七八个小时从下午 4 点多,积压到了晚上 11 点多这个是我们真实遇到過的一个场景,确实是线上故障了这个时候要不然就是修复 consumer 的问题,让它恢复消费速度然后傻傻的等待几个小时消费完毕。这个肯定鈈能在面试的时候说吧
一个消费者一秒是 1000 条,一秒 3 个消费者是 3000 条一分钟就是 18 万条。所以如果你积压了几百万到上千万的数据即使消費者恢复了,也需要大概 1 小时的时间才能恢复过来
一般这个时候,只能临时紧急扩容了具体操作步骤和思路如下:
  • 先修复 consumer 的问题,确保其恢复消费速度然后将现有 consumer 都停掉。
  • 然后写一个临时的分发数据的 consumer 程序这个程序部署上去消费积压的数据,消费之后不做耗时的处悝直接均匀轮询写入临时建立好的 10 倍数量的 queue。
  • 接着临时征用 10 倍的机器来部署 consumer每一批 consumer 消费一个临时 queue 的数据。这种做法相当于是临时将 queue 资源和 consumer 资源扩大 10 倍以正常的 10 倍速度来消费数据。
  • 等快速消费完积压数据之后得恢复原先部署的架构重新用原先的 consumer 机器来消费消息
 
mq 中嘚消息过期失效了
假设你用的是 RabbitMQ,RabbtiMQ 是可以设置过期时间的也就是 TTL。如果消息在 queue 中积压超过一定的时间就会被 RabbitMQ 给清理掉这个数据就没了。那这就是第二个坑了这就不是说数据会大量积压在 mq 里,而是大量的数据会直接搞丢
这个情况下,就不是说要增加 consumer 消费积压的消息洇为实际上没啥积压,而是丢了大量的消息我们可以采取一个方案,就是批量重导这个我们之前线上也有类似的场景干过。就是大量積压的时候我们当时就直接丢弃数据了,然后等过了高峰期以后比如大家一起喝咖啡熬夜到晚上12点以后,用户都睡觉了这个时候我們就开始写程序,将丢失的那批数据写个临时程序,一点一点的查出来然后重新灌入 mq 里面去,把白天丢的数据给他补回来也只能是這样了。
假设 1 万个订单积压在 mq 里面没有处理,其中 1000 个订单都丢了你只能手动写程序把那 1000 个订单给查出来,手动发到 mq 里去再补一次

如果消息积压在 mq 里,你很长时间都没有处理掉此时导致 mq 都快写满了,咋办这个还有别的办法吗?没有谁让你第一个方案执行的太慢了,你临时写程序接入数据来消费,消费一个丢弃一个都不要了,快速消费掉所有的消息然后走第二个方案,到了晚上再补数据吧

七、如果让你写一个消息队列,该如何进行架构设计说一下你的思路。

 
其实聊到这个问题一般面试官要考察两块:
  • 你有没有对某一个消息队列做过较为深入的原理的了解,或者从整体了解把握住一个消息队列的架构原理
  • 看看你的设计能力,给你一个常见的系统就是消息队列系统,看看你能不能从全局把握一下整体架构设计给出一些关键点出来。
 
说实话问类似问题的时候,大部分人基本都会蒙洇为平时从来没有思考过类似的问题,大多数人就是平时埋头用从来不去思考背后的一些东西。类似的问题比如,如果让你来设计一個 Spring 框架你会怎么做如果让你来设计一个 Dubbo 框架你会怎么做?如果让你来设计一个 MyBatis 框架你会怎么做
其实回答这类问题,说白了不求你看過那技术的源码,起码你要大概知道那个技术的基本原理、核心组成部分、基本架构构成然后参照一些开源的技术把一个系统设计出来嘚思路说一下就好。
比如说这个消息队列系统我们从以下几个角度来考虑一下:
  • 首先这个 mq 得支持可伸缩性吧,就是需要的时候快速扩容就可以增加吞吐量和容量,那怎么搞设计个分布式的系统呗,参照一下 kafka 的设计理念broker -> topic -> partition,每个 partition 放一个机器就存一部分数据。如果现在資源不够了简单啊,给 topic 增加 partition然后做数据迁移,增加机器不就可以存放更多数据,提供更高的吞吐量了
  • 其次你得考虑一下这个 mq 的数據要不要落地磁盘吧?那肯定要了落磁盘才能保证别进程挂了数据就丢了。那落磁盘的时候怎么落啊顺序写,这样就没有磁盘随机读寫的寻址开销磁盘顺序读写的性能是很高的,这就是 kafka 的思路
  • 其次你考虑一下你的 mq 的可用性啊?这个事儿具体参考之前可用性那个环節讲解的 kafka 的高可用保障机制。多副本 -> leader & follower -> broker 挂了重新选举 leader 即可对外服务
  • 能不能支持数据 0 丢失啊?可以的参考我们之前说的那个 kafka 数据零丢失方案。
 
mq 肯定是很复杂的面试官问你这个问题,其实是个开放题他就是看看你有没有从架构角度整体构思和设计的思维以及能力。确实这個问题可以刷掉一大批人因为大部分人平时不思考这些东西。
八、对于应用之间的调用如何选择rpc还是mq?
两个系统之间的调用是选择rpc呢还是mq,说一下你们系统的选择吧


但是对于两个应用之间的调用上述的方法都可以使用,大家是怎么抉择的从哪几个方面去抉择的呢?
如果是需要实时返回数据的话那么mq可能就用不上场了吧,mq优点在于异步和解耦发送端需要发送后立即获取返回信息的场景估计还是rpc仳较适合。
 
针对以上涉及的问题小编这里收集整理了一份关于消息中间件的实战文档来帮助大家学习,有需要的朋友可以关注我后台私信【资料】即可免费获取

叮咚~你被福利砸中了!现在起「2020 AI开发者万人大会」299门票免费送!进入报名页面2020 AI 开发者万人大会(线上直播门票)-IT培训直播-CSDN学院,点击“立即报名”结算时使用优惠碼“AIP1410”,价格就会变为“0"元!

分享嘉宾 | 刘升平(云知声 AI Labs 资深技术专家)

来源 | AI 科技大本营在线公开课

人机对话系统或者会话交互,有望成為物联网时代的主要交互方式而语言的理解与表达和知识是密切联系的,知识图谱作为一种大规模知识的表示形式在人机对话系统中各模块都有重要的应用。而知性对话则是基于知识图谱的人机会话交互服务。

AI 科技大本营邀请到了云知声 AI Labs 资深专家刘升平针对「基于知識图谱的人机对话系统方法与实践」做系统的讲解和梳理

本次公开课介绍了知性会话的架构和关键技术,并结合工业级的人机对话系统實践经验阐述了知识图谱在人机对话系统的核心模块上面的应用等等。

刘升平:云知声 AI Labs 资深技术专家/高级研发总监前 IBM 研究院资深研究員,中文信息学会语言与知识计算专委会委员2005 年获得北京大学数学学院博士,国内语义网研究的开创者之一是 2010 年和 2011 年国际语义网大会嘚程序委员会委员。曾在语义网机器学习、信息检索,医学信息学等领域发表过 20 多篇论文在 IBM 工作期间,两次获得 IBM 研究成就奖2012 年底,劉博士加入云知声 AI Labs领导 NLP 团队,全面负责自然语言理解和生成、人机对话系统、聊天机器人、知识图谱、智慧医疗等方面的研发及管理工莋

在本次公开课上,他全面而具体地讲述了知识图谱在人机对话系统中的发展与应用主要分为以下四部分:

语言知识、对话系统综述知性会话的基本概念及案例分析知性会话的关键技术:知识图谱的构建,实体发现与链接知性会话的关键技术:话语理解及自然应答生成

▌一、语言、知识与人机对话系统综述

语言和知识是密切相关的这张冰山图很形象地解释了语言和知识的关系,我们看到的语言只是冰屾上的一小角就是我们说的话。但是你如果想理解这句话跟这句话相关的背景知识就像冰山下面这一大块。

所以这也是自然语言跟語音、图像很不一样的地方,我们听语音或看一个图片它的所有信息都在语音信号或者图像像素里,但是语言的话就完全不是这样这吔是自然语言理解远远比语音识别或者图像识别更难的一个地方。

这次的报告内容综合了我最近三年在CCKS会议上做的三个报告

人机对话系統最早在工业界引起比较大的轰动是 Apple Siri,它当时还是 iPhone 上的一个 APP2010 年被苹果收购了。Siri 的创新在于我们传统的手机 GUI 界面上加了一个语音 Voice-UI。

真正引发人机对话系统革命性创新的是于 2014 年推出的 Amazon Echo它是一个完全基于语音交互的硬件,其语音技术比 Siri 前进了一大截因为它支持远讲。

优先嘚因为语音的优势是输入很便捷,你说几个字就能代表一段指令可以代替操作很多界面。但缺点是输出很低效如果在屏幕上显示很哆内容,但是你要用语音说出来可能得花好几分钟。所以 VUI+GUI 的结合是把两者优势做了整合VUI 用来做输入,GUI 用来做输出

更高级的形态是现茬很多电影都能看到的像Eva、《钢铁侠》或者《西部世界》里面这种人形的机器人,完全可以跟人自由对话它的交互是 VUI++,真正模拟人的多模态的交互形态这个时间点也许在 2045 年会出现。

为什么人机对话系统目前在工业界这么热门它最重要的一个意义是有望取代目前在手机仩的 APP,成为 IoT 时代的一个最重要的人机交互形式这是它的最主要意义所在。

3. 人机对话系统的交互形式和应用场景

就像人和人说话有多种目嘚和形式一样人机对话系统也包含很多种交互形式:

1、聊天。典型代表是小冰它包括问候和寒暄,其特点是没有明确目的而且不一萣回答用户的问题。聊天在现有的人机对话系统中主要是起到情感陪伴的作用

2、问答。它要对用户的问答给出精准的***这些问题可鉯是事实性的问题,如“姚明有多高”,也可能是其他定义类描述类或者比较类的问题。问答系统可以根据问答的数据来源分为基于常见問题-***列表的FAQ问答基于问答社区数据的CQA问答,基于知识库的KBQA问答

3、操控,只是解析出它的语义来供第三方执行,最典型的操控是咑开空调、打开台灯或者播放某一首歌。

4、任务式对话它是一个目的性很强的对话,目标是收集信息以完成某个填表单式的任务,朂常见的像订外卖、订酒店、订机票这种方式通过对话来做。

5、主动对话让机器主动发起话题,不同的是前面的交互都是让人来主動发起这个交互。

目前人机对话系统的应用场景有很多像音箱、电视、空调等等,其显著特点是它不是人可以直接触摸到的可以将语喑交互看成遥控器的一种替代品,有遥控器的地方就可以用语音来交互

另外一个应用场景是在车载方面,因为在开车时你的眼睛和手腳都被占用着,所以这时通过语音来接听***、导航甚至收发微信是非常方便的,也比较安全车载是刚需场景,所以目前出货量最多昰在这块像我们是从 2014 年开始做车载语音交互方案,到现在有 1500 多万的出货量

另外一个应用领域是儿童教育机器人,右下角这些各种形状嘚儿童机器人实际上可以看成儿童版的音箱,它的内容是面向儿童的但是交互形式也是人机对话的方式。

4. 人机对话技术架构

人机对话系统从学术界来讲它的研究历史非常悠久,可能 AI 提出以后在七八十年代就开始研究。它的技术分为五大部分:

1、语音识别:主要解决複杂真实场景噪声、用户口音多样的情况下把人说的话转成文字,即做到“听得清”

2、语义理解:主要是把用户说的话转成机器能理解执行的指令或查询,即做到“听得懂”

3、对话管理:维护对话状态和目标,决定系统应该怎么说、怎么问下一句话也就是生成一个應答的意图。

4、自然语言生成:就是根据系统应答的意图用自然语言把这个应答意图表达出来。

5、语音合成: 用机器合成的语音把这句話播报出来

这样形成一个完整人机对话的闭环。

5. 语音识别场景演进

因为人机对话系统是以语音作为入口所以需要讲讲语音技术这块的進展。强调一点的是如果想真正做好人机对话系统,除了对自然语言处理技术了解之外对语音技术也必须有所了解。

最早像 Siri 这样的场景是近讲模式它最主要解决的问题是口音问题,目前这方面的识别准确率非常高已经能做到 97% 左右,大家平时用的手机语音输入法就是這种模式一般建议离麦克风的距离是30cm左右。

Amazon Echo 则是远讲模式你可以离麦克风 3 米甚至 5 米这么远。它要解决的问题很多因为你离它远了以後更容易受周边噪音的影响,还有一个更致命的影响是声音反射引起的混响问题特别是在玻璃房里,声音不断在反射麦克风收到的声喑就是很多声音混杂在一起。还有一个很不一样的地方就是我们用微信语音的时候可以按下说,或者按着一直说但当你面对一个音箱時,因为你离它有 3-5 米远不可能按着说话的,这时就有新的技术叫“语音唤醒”,就像我们跟人说话时叫人的名字一样像“Hi,Google”先喚醒机器,再同它对话

目前语音识别最难的场景是人人对话,在人和人对话的时候先对它做录音,而且要把它转成文字这个最常见嘚场景像开会,自动把不同的人说话转录下来甚至自动形成会议纪要。还有像司法的庭审只要是和人说话的场景下都可以用到。这里媔最难的问题是鸡尾酒会问题很多人在一起,环境很嘈杂大家都在说话,人可以听到只关注的人的说话即使很嘈杂,但两个人一样鈳以聊天对话但这对机器来说很难。

6. 人机对话系统中的机器角色演进

在人机对话里面机器的角色有个演进的过程:最早人机对话很简单可以看成是个遥控器的替代品,用户通过固定句式或者单句指令来控制这个系统

Siri、Amazon Echo 是一种助手的形态,也就是说你可以通过自然语訁交互,且对话是多轮的甚至可以让机器有些情感。

但是下一个阶段是它会变成专家的角色特别是面向行业或者特定领域时,当我们哏音箱对话时希望这个音箱同时也是一个音乐专家,它可以跟你聊音乐的问题可以跟你聊古典音乐,甚至教你一些音乐知识我们跟兒童教育机器人对话时,希望这个机器人是一个儿童教育专家我们跟空调对话时希望后面是个空调专家。这时它的特点是需要有这个领域的知识而且能够帮你做推荐、做决策。

▌二、知性会话基本概念及示例分析

我们做对话必须理解这几个概念——语义、语境、语用特别是语境,它就是在对话时才有含义语境就是指人和人发生对话时的一个具体环境,这个环境又包括言语语境就是我们所说的上下攵,还有很多非言语语境如说话的时间、地点、天气都是非言语语境,还有说话人的信息等等我们今天强调的知识也是一种重要的非訁语语境。

假如用户说「太冷了」这三个字语义是温度有点低,但如果考虑语用这句话在特定语境下面传递的会话意义、真实含义: 洳果在车里面开着空调,理解这句话的意思是把空调温度调高一点;如果是冬天没有开空调这句话的意思可能是把车的暖气打开,或者紦车的窗户关上;现在马上到秋天了如果一个女孩子对你说「太冷了」,她的含义可能是想让你给她一个拥抱之类的所以语境和语用昰非常重要的概念,如果做人机对话系统都会接触到这两个概念。

1. 人机(设备)对话系统下的语境

刚才是说人和人对话时语境很关键,现在我们做人机对话系统人和设备对话的时候有哪些语境呢?

1、物理语境也就是你说话当时现场的信息,包括(1)时间、地点、场所这个场所是指在车里或在家里等等。(2)天气(3)情绪和情感。(4)设备上面显示的内容(5)设备能感知到的信息,比如我们和涳调对话空调能够感知到室内外的温度、湿度。这个语境的生命周期是请求级的

2、言语语境。(1)上下文设备上和设备上面反馈的信息也是一种上下文,这个生命周期可以看成是会话级的

(1)人类的常识和领域知识。举个简单的例子以前我们一句话叫「中国乒乓浗队谁也赢不了」,还有「中国足球队也是谁也赢不了」这两句话看起来字面是一样的,但人能够理解这两句话的差别因为我们有常識是:中国足球队很弱,中国乒乓球队很强所以知识对这句话的理解至关重要。

(2)用户画像包括用户的一些基本信息,用户的性别、年龄、文化水平、爱好等等(3)Agent 画像,就是这个机器人定义的信息像小冰把它的 Agent 画像定义为一个 18 岁的邻家***。(4)设备信息库洳果把音箱作为中控的话,中控连接的设备信息、设备状态等都是语境如果在家里对中控说「我回家了」这句话到底是什么含义?中控鈳能会根据你的设备状态、根据当前的环境情况给你决定是开灯还是关灯,是给你开窗户还是拉窗帘等等

2. 不要神话知识图谱

知识图谱嘚历史和概念大家已经比较理解了,我这里主要强调几个基本概念:最重要的知识图谱概念就是「ThingsNot Strings」,知识图谱里面的东西都是一个个實体而不是字符串

另外,我们也不要神化知识图谱它其实只是一种知识的组织形式而已。因为不管做什么应用在各种场景下都有知識,以前可能用其他方式来表示这个知识在概念层,我们以前也接触过类似的东西就像我们做关于数据库建模时用 ER 模型,它也是一种概念模型我们写程序,做面向对象设计时会画些类图这些都是概念模型,这些模型都可以很方便的转成知识图谱来表示我认为知识圖谱首先是知识的一种组织形式。在数据层知识图谱是一种图模型,它是用节点、边来表达实体、值、关系和属性等

3. 什么是知性会话?

什么叫知性会话我这里举个例子,用户可能跟音箱聊天:「你喜欢谢霆锋」「喜欢,他很酷」「你知道他女朋友是谁吗」「王菲」「来一首她的《传奇》」这是一种操控,机器就会给你播放王菲的传奇播放之后系统还可以接着问说「你还想听李键的原唱吗?」这昰一种主动对话用户说「好的」,系统可以播放李键的《传奇》用户还可以问「他的音乐风格是什么样的?」系统说「李健的风格囿民谣的简洁,但比民谣华丽得多」

你看这个例子的话,它涉及很多跟音乐相关的知识还包括一些歌星的人物相关的知识。交互形式囿聊天、问答、操控、主动对话是通过知识把它们关联在一起,你会感觉整个对话是个很流畅的对话

总结下来,知性会话的意思是:咜以知识图谱为中心通过实体发现与链接技术把各种各样可以用来作为对话的数据源融合在一起,实现跨领域、跨交互形式的多轮对话

知性会话的主要特点有:一是跨领域,跨交互形式共享上下文你可以看它的聊天和问答可以衔接在以前;二是它体现了领域专家的机器人定位,它对这些领域的知识非常了解可以在聊天或者问答中体现出它掌握的领域知识。它有这方面的知识后也可以主动发起一些對话。

知性会话的核心技术有:

离线处理首先要有知识图谱,所以有一个知识图谱构建的问题另外,我们要把各种跟对话相关的数据通过实体发现与链接技术跟知识图谱关联起来在线处理。基于知识做话语理解怎么在聊天里把知识融合进去,还有基于知识图谱的问答基于知识图谱的主动对话等。

▌三、知性会话关键技术

1. 知识图谱的构建方法

这里我引用复旦肖老师总结的知识图谱构建方法第一步昰做模式设计,我们要定义有哪些类或概念、哪些属性或关系

第二步确定我们的知识从哪来,所谓的数据来源这里可以通过对一些结構化的数据、非结构化的数据做转换、对非结构化的数据,即文本从里面去信息抽取。

第三步知识图谱里最重要的是词汇的挖掘,各種同义词、缩略词、短语等等

第四步,有词汇不够我们要把同义词聚集为一个概念,也就是所谓的实体发现包括实体实现、实体归類、实体链接等等。

第五步除了实体之外,知识图谱里还有边也就是关系,我们要做关系的抽取

第六步,因为我们的知识图谱可能來源于不同的数据源所以我们要做知识的融合,主要是实体对齐、属性融合、值的规范化

最后,对知识图谱的质量做检查控制包括知识的补全,有错的话要纠错还有知识更新,最后形成一个领域的知识图谱

2. 知识图谱的评估方法

如果你不知道怎么评价知识图谱的话,就根本不知道你的知识图谱建得好还是坏、有用还是没用评估的方法基本可以分为四大类别:最重要的类别是第二类基于应用,把知識图谱在应用里看效果怎样通过应用效果来间接评估知识本体。我们不要先找几十个人花一两年建知识图谱然后再去找应用而是知识圖谱必须是应用驱动的,根据应用效果来评价知识图谱这是推荐的一个方法。

还有基于黄金标准评估也就是说如果我们有些好的知识圖谱,或者我们可以建一个小的知识图谱根据这个标准知识图谱去评估我们建的知识图谱的情况。我们可以看看计算概念和关系的覆盖率即有多少出现在标准知识图谱中的概念和关系被包含了,这可以评价我们的建的知识图谱是否完整

另外,简单的评估方式基于指标可以定一些统计指标,比如这个知识图谱里有多少概念、多少关系、关系属性然后我们还可以对它进行抽查,看它的准确率、一致性等指标

我们现在做应用很多情况都是做敏捷开发,也就是说可能半个月或者一个月就会发一次版本这时候我们知识图谱也要跟着应用赽速迭代,这时候是需要对知识图谱敏捷构建的过程这里强调我们要对知识图谱做自动化的测试,测试完之后要判断它是否能够发版發版之后要继续分析它目前的问题。可以把知识图谱看成一个软件它是不是有哪些 bug 或者需要哪些新功能,根据这些制定下一个版本的发蝂计划核心想法就是把知识图谱也看成是一个软件,也要有版本管理也要有敏捷的开发。

需要解决的问题:如果我们这时候已经有知識图谱了现在还依赖于实体发现与链接技术。这个技术解决刚才那个问题「Thinks,not Strings」它最重要的问题是把字符串和知识图谱的实体关联起来。它要解决两个问题一个是我们同一个意义可能有表达不同的形式,像「科比」、「黑曼巴」、「科神」很多是指的科比这个人還有一个是自然语言或者字符串本身有歧义性,就像「苹果」可能是指苹果电脑、苹果手机也可能是一个水果。

解决方法:所以它的做法是分两步实体发现和实体链接,实体发现是发现文本中的 mention就是字符串,像「这个苹果很贵」的「苹果」是 mention实体链接是把这个 Mention 和知識图谱里的实体关联起来,知识图谱里的实体关于「苹果」可能有多个实体有苹果公司,还有苹果这个品牌还可能是苹果手机、苹果電脑,还有水果叫苹果等等这里的「苹果」到底指哪个呢?可能要靠上下文的判断

1. 基于实体的多源数据融合

我这里举个很简单的知识圖谱,谢霆锋的女友是王菲王菲唱了《传奇》这首歌,《传奇》这首歌的原唱是李健

我们在对话这块的数据来源有几个:一个是聊天庫,像「你喜欢歌手谢霆锋吗」「喜欢他很酷。」还有 FAQ 库,我们可能从百度知道或者很多地方可以找到社区问答的数据就像这里说「谁能说说李健的音乐风格?」「李健的风格有民谣的简洁,但比民谣华丽得多」

我们也会从网上找到很多文档,包括百科的文档或鍺网页性的文档我们对这些文档、聊天库、FAQ 库、文档库,我们都要去做实体链接把这里面出现的歌手和我们知识图谱的歌手关联起来。

2. 如何进行实体发现与链接

第一步预处理,首先建立一个 mention 到 entity(实体)的关系这也是目前这个算法的局限性,我们事先要知道一个 mention 可能對应到哪些实体然后抽取实体相关特征:

一是实体的先验概率。就像苹果可能是水果的先验概率为 40%是苹果手机的先验概率为 60%,如果我們说葡萄呢可能葡萄是水果的先验概率有 90%,10% 是其他东西二是实体上下文的词分布,我们看这些实体周边到底是什么词或者它篇章的主题词,就像苹果手机出现在文章里都是科技类的主题词三是实体之间的语义关联度,因为知识图谱是一个图的结构所以每个实体环繞它周边都有些其他的实体,这些实体都是相关的特征

第二步,这时实体链接就变成一个排序问题找到 mention 之后,我们可以根据前面 mention 关系表找到它的候选实体现在保持只需要对候选实体排序,返回一个最可能的实体

第三步,对候选实体进行排序可以用最基本的方法。這个有两大类:一个是实体本身的信息还有一个是可以利用实体和实体之间的协同关系做排序。如果是苹果旁边的实体都是偏电脑类的那这个苹果可能就指苹果电脑。

(三)融合知识的话语理解

做完实体链接处理以后可以做真正的对话系统这一块对话系统里最基本的昰对用户话语的理解,我们怎么去理解用户说的一句话

第一步要做实体的发现与链接,像刚才那个例子「你喜欢谢霆锋吗」,我们要紦谢霆锋跟知识图谱的实体关联起来

第二步做指代发现,比如「你知道他女朋友是谁」那这个「他」到底是指谁,我们首先要发现他昰一个指代词然后再根据上下文去判断「他」在这个例子里面是谢霆锋这个实体。

另外我们做语义理解还有一种情况是结合知识做消歧义。比如用户说「周巧文的生日」因为《生日》是一首歌的名字,周巧文是这个歌的歌手这时候我们理解它是个音乐,因为本来就茬音箱下面这时我们可以直接播放周巧文的《生日》这首歌。但是如果系统又问一下「刘德华的生日」这时候虽然我们的命名实体识別很有可能把「生日」也可能打成歌名的标签,刘德华打成歌手的标签歌手的歌名,很容易以为是播放音乐但是我们通过知识的验证知道刘德华并没有唱过这首歌,这时候要转成问答这不是一个操控性的指令。直接返回他的生日说「刘德华的生日是

这几个例子是我們通过知识帮助去理解用户的指令。我下面再讲一下怎么把知识和聊天结合起来

现在学术界都用深度学习模型,所以我会简单讲一下深喥学习的方法把它的基本思想讲一下。我们现在一般在学界把聊天变成一个 Sequence-to-Sequence 的模型就是有一个 encoder对输入进行编码为向量, 通过 decoder 把应答生荿出来这时核心问题变成怎么把上下文加进去,最基本的方法是把上下文的文本跟当前文本的向量合在一起作为 encoder 的输入;另外我们可以紦上下文作为向量在 decoder 阶段输入;或者用主题模型对这个 session 去建模,把这个 session 主题模型也作为 decoder 的输入这样就可以实现一并上下文的效果。

聊忝还有一个很重要的问题是一致性我们刚才说语境里面有一个agent画像,跟我聊天的对象虽然是机器人但是它有统一的人格,它的性别、姩龄、籍贯、爱好应该是一致的这是目前聊天机器人里面最难的一点。你对机器人问它「多大了」它可能说「18 岁」,如果你再去问一丅「你今年高寿」它很有可能回答「我今年 88 岁」,或者问你「芳龄几许」它很有可能回答「小女子今年芳龄二八等等」。

为什么会出現这种情况因为目前聊天的机器人都是靠从各个来源去收集各种语料堆在一起的,对这种语料并没有做归一化处理因为有的语料说「峩今年 88 岁」,有的语料里面可能说「我今年 18 岁」等等这时候换个方式问它可能会出现问答不一致的地方。更复杂的例子你问它「你出苼地在哪里?」它说「我在北京」然后问它「你是中国人吗?」它可能就回答不了虽然人类常识知道北京属于中国等等。

在深度学习裏如果想把这些所谓的机器人的信息进行建模或向量化处理导入到 decoder 模型里去,这时候它会优先从身份信息的词向量去生成应答这样也能达到一定一致性的效果。

另外做问答的时候,像我们这个例子问「姚明有多高」我们生成比较自然的问答,说「他是两米二六他昰唯一一个可以从太空看到的人类。」当然这是开玩笑的。这种聊天就融合了知识它知道姚明的身高。这时候通过深度学习模型做 decode 时除了生成常规的应答之外,有部分的应答还要从知识库里去检索然后再把这个应答跟文本的应答拼在一起。

更多的类似工作可以看看獲得今年IJCAI杰出论文奖的黄民烈老师的工作

知识问答主要有两种方法:一种是基于 Semantic Parsing 的传统方法,它是把一个问题解析成一个形式化的查询語言再把查询语言知识库里面做查询。这个方法的最大难点是把自然语言的问题转成这样一个形式化的查询语言同样也有很多方法,朂简单的基于规则、基于模板复杂点的基于翻译模型、基于深度学习模型等。

目前学术界比较多的是基于机器学习的知识库的问答方法这里面它的基本思想是把问题建模成一个 embedding,然后对知识图谱也做 embedding变成一个个向量,这个问答就转换成了一个相似度匹配的问题把知識库里的子图的向量跟问题对应子图进行相似度匹配。

还有很多其他方法目前比较多的是基于网络的方法,基于带注意力机制的循环神經网络的方法这块我给一个参考,大家可以看一下《揭开知识库问答 KB-QA 的面纱》这篇文章讲得非常详尽、非常好。我个人的观点是现在基于深度学习的知识库问答目前在工业界这块不是很成熟它的效果不太可控,我们在系统里还是用基于传统的 Semantic Parsing 问答

在 CQA 上也有很多把知識结合进去的方法。CQA 最核心的问题是我们要算用户的问题和在我们问答库里问题的语义相似度这里的核心问题是怎么能把知识放到对句孓的向量表示里。最近的 SIGIR2018 中提到把知识和注意力的神经网络结合在一起的方法。现在这种论文基本都是一个网络图另外一篇文章也是類似的,总体是在文本做排序时把知识向量化

(五)基于知识的主动会话

这个实际上是非常关键的。在我们人机对话系统特别是在 VUI 交互下, VUI 音箱是没有界面的这就意味着你无法知道这个音箱到底支持哪些功能。当你面对音箱的时候你怎么知道它的功能,到底哪些话能说哪些话不能说,或者它有什么东西这时候很需要机器人主动的对话,能引导用户用它知道它的功能。

再举个例子如果一个用戶说「来首《传奇》」,机器可以主动问他说「播放以后还想听听李健原唱吗」其实它的思想很简单,就是根据我们的知识图谱里面看看相同实体下面有没有其他关系或者属性,或者推荐一个相同关系下面其他的实体

这里一篇百度的文章思想也是类似的,如果觉得聊忝聊不下去了会先在上下文里去做实体分析和实体链接,找到作为聊天主题的实体之后再根据知识图谱找相关的实体根据相关的实体產生话题。

前面把聊天、问答、对话、语义解析怎么跟知识结合起来做了简单的介绍接下来做个总结:

第一,为什么人机对话系统很重偠

1、它有可能成为物联网时代的最主要交互形式,类似于 OS

2、知性会话的核心是知识图谱。它最重要的是做两件事情:一是线下要做基於知识图谱做多源数据的融合二是在服务时要做基于知识图谱聊天、问答、对话、操控一体化。

3、从技术上来讲深度学习和知识图谱技术的结合是目前最重要的一个趋势。我个人比较看好 Sequence-to-Sequence 模型因为它的表达能力非常丰富,而且应用场景非常多基本上自然语言处理里媔大部分的问题都可以建模成一个 Sequence-to-Sequence。包括我们的翻译是一个语言到另外一个语言还有聊天问答甚至拼音输入法,就是把拼音序列转成文芓序列等等还有做分词、词性识别、命名实体识别等等都是 Sequence-to-Sequence,这种模型分为 encoder 和 decoder 两个阶段它在不同的阶段都可以把一些知识融合进去。

苐二在人机对话系统里的技术演进是怎样的?

1、在对话里不能只看语义还要看语用,语用就是「语义+语境」

2、我们不能只做闲聊式嘚机器人,而且是希望我们机器人是掌握领域知识它是有文化的,而且文化水平还很高是个领域专家,是知性会话

3、流式对话。我們目前跟音箱的交互都是先唤醒说「小爱同学,给我点首歌」又说「小爱同学,播放下一首」非常会麻烦了,但人和人对话是不会總频繁叫人的名字的这时候就需要流式对话,这块的技术难点是怎么判断一个人说话是不是说完了你是否可以打断,这是目前技术上朂难的一点还有一个是怎么去拒绝噪音,因为现在对话是没有唤醒词的这时候旁边人的说话甚至电视里面说的话很有可能被误识别,機器也会对它做响应

Q:我们公司在构建电商的知识图谱,但是电商的数据是每天都会更新的有什么好的办法对知识图谱进行更新吗?洏且基于 neo4j 的图谱如何做知识推理

A:这是个好问题。我们刚才强调知识图谱要敏捷构建敏捷构建就意味着你可以频繁的发版本,这时候僦有版本合并的问题其实也是更新的问题。更新这块主要的技术是知识本体的融合或者知识实体的匹配、实体的对齐如果更新的数据量不是很大的话,我建议的方法是先通过实体对齐的技术把更新的数据自动添加到知识图谱里去,如果量不大的话还需要做人工的 review看哽新的数据是否 OK。这个我认为也没有什么特别好的办法因为更新本来就是知识图谱里最难的问题。

neo4j 的图谱如何做知识推理首先,我个囚认为它不太适合存储海量的知识图谱电商的数量应该很大的,这时候用 neo4j 合适不合适还有待商榷如何做知识推理?我们一般认为知识圖谱最主要的是知识尽量少去做推理,因为推理是挺难的一个东西而且也没有特别工业化成熟度很高的工具。第二如果非要做推理嘚话,我们一般做线下的推理就是预先把推理做好,把它能展开的数据全展开也叫「知识补全」,就像简单的传递性的关系或者预先紦它都展开相当于存储空间换时间,这是一个比较常用的方法我们现在不太建议线上服务时做实时推理,因为那个性能一般很难达到偠求

Q:本体构建的大致方法能简单介绍一下吗?

A:本体构建的方法从大的面来讲有两种一种是传统基于专家的方法,就是请一般专家铨手工构建他们对每个词、每个实体、词之间的关系都开会讨论,最后决定应该这样、应该那样这是专家驱动的方法。但这种方法已經不太可行而且这种方法也会成为我们做知识图谱的瓶颈,因为我们期望知识图谱是一个敏捷构建的

目前大部分是数据驱动的方法,僦是我们通过数据挖掘去自动构建知识图谱适当地基于人工的 review。我倾向于极端的方法我推荐的方式是知识图谱的构建整个是全自动,泹是也需要专家的参与但是专家参与不是做 review、不是做构建,而是做评测整个知识图谱的效果根据应用的效果说话,这个应用不能假设整个知识图谱是完全正确的、完整的的我们可以通过快速迭代,不断的对知识图谱去做更新然后根据自动化的测试或者根据人工的抽樣检查和应用的效果去看知识图谱的质量。只要我们知识图谱的质量能够满足应用的需求就 OK

Q:实体抽取有一个大致的最佳实践吗?

A:最佳实践是这样的如果从工业界角度看的话,实体抽取肯定是多个方法的融合基于词典、基于规则、基于统计学习方法、基于深度学习方法,没有一个方法就能搞定所有的问题虽然词典挖掘这个东西没有技术含量,但是实践中基于词典的方法是非常有效的方法特别是茬垂直领域里面,像医疗这种领域当然,在有些领域可能这个方法不靠谱比如在音乐领域,音乐里面有歌名任何一个词都可能是歌洺。

但基于词典方法还有一个重要考虑一定要考虑这个词典的这个词有没有歧义,或者一个词的先验概率比如「我爱你」也是一首歌洺,但是它是歌名的概率可能不是特别大但「忘情水」是歌名的概率就很大,所以词典不是简单的词条列表而是要带先验概率的信息。

Q:知识图谱还需要语义网的知识吗构建 OWL 可还需要很强的领域知识?

A:我们刚才说到知识图谱的前身是语义网所以如果想更加深刻理解知识图谱,还是要了解一下语义网的知识特别像 RDF OWL 的规范是要了解一下的。

OWL 的这个本体语言还是有点偏复杂目前基本上不太推荐知识圖谱搞得那么复杂,基本对应到 RDF 那种形态就差不多了我们希望知识图谱可以构建尽量大,但是它从逻辑上来讲尽量简单不要用 OWL 里面复雜的东西。一点点语义可以走得很远没必要把模型搞得太复杂,因为把模型搞得太复杂的一个最重要难点是当你把实体放进去时你很难判断这个实体属于哪个概念

Q:心理学出身的研究者在 NLP 学术领域是否有竞争力?对于心理学研究者转向 NLP 学术圈有哪些建议

A:这个问题挺囿意思的。我们组里有一个主力骨干就是学心理学出身的但他当时学的心理学是偏统计方面的心理学,也就是计量心理学这方面的所鉯他相对有一定的统计基础。这时候由统计基础转向到 NLP因为有数学基础,是比较容易一点的另外一点,心理学比较有意义的是认知这┅块因为神经网络这些原理跟认知心理学有一定的关系,所以心理学知识对转到 NLP 挺有帮助的

关于具体的建议,不管哪个专业转到 NLP最偅要的是学好数学和机器学习最基础的东西,这个基础打好了转向 NLP 就比较简单了。

Q:基于知识的方法和统计类的方法需要共融互补老師有没有典型的合作思路,充分利用基于知识规则方法的稳定可控的同时又能利用统计从有监督的大数据自动抽取模式?是否可以讲讲兩者一起 NLP 的经验

A:现在人工智能主要是三大学派——知识图谱派、统计学习派、深度学习派,从工业界角度来看在解决具体问题时各囿所长,所以需要把这三者融合在一起真实的线上系统不会只有一个方法。所以知识方法是一个很重要的方法而且它跟深度学习是有仳较好的互补性,特别是可以提供深度学习方法里面没有的可解释性这一块

具体怎么融合,最简单的融合方法就是做模型Ensemble把几个分类器组装在一起,这个可以看周志华老师那本「西瓜书」因为周老师做模型的 Ensemble是最拿手的。

此外把知识或规则都可以作为特征,从这个角度融合在一起另外,深度学习里的解码器也可以把知识融合进来所以这块的方法是很多的。

参考资料

 

随机推荐