Many Links 0619

NON-Tech
1.
看这篇文章,体会下感受下生在互联网时代,20世纪形成的政治体制正在变得“古老”的路上。
毕竟,现在有多少人会觉得 马基雅弗利的政治“智慧”没有过时?
道德危机的起源 The Making of a Moral Crisis
“many-chambered heart of the internet”(不知怎么翻译) 如何将特朗普政府的家庭分离政策变为另一种丑闻
https://www.theatlantic.com/technology/archive/2018/06/the-making-of-a-moral-problem/563114/
如果没时间可以速读谷歌翻译出来的中文,下面是我从google翻译里摘抄部分

像劳拉布什所说的那样,2岁以下的孩子已经从父母那里被带走,转移到“二十世纪二战日本美国拘禁营”的“令人毛骨悚然的”设施。 家庭正在分居。 孩子们正在笼子里的金属箔毯下睡觉。
这个故事受到如此多关注的主要原因很简单:这太可怕了。 当然, 大多数显示哭泣孩子的图像或者听到他们录音的孩子 的美国选民都呼吁为他们的父母提供强烈的消极反应。
但在当今分裂和陌生的媒体环境中,更难以回答的问题是如此多的人最终看到这些图像并听到这些故事。 毕竟,这可能是美国边界上最臭名昭着的不公正,但这不是第一次。

美国人喜欢相信透明度,就像路易斯·布兰代斯法官曾经说的那样,“阳光据说是最好的消毒剂”。但是阳光不再仅仅来自报纸头版或电视广播塔。 这是Facebook视频和模因,微博风暴和病毒图片。 虽然这并不是说这个故事只是从互联网的角落冒出来的。 移民局和调查记者已经上了一年多。 参议员卡马拉哈里斯在12月首次谈到这件事。 但直到5月底才成为该国最大的新闻。 怎么样?

但是没有任何来自边界的报道可以说明发生了什么。 有不祥的报道,但不是真实的人的考验故事。
然后在纽约时报上刊登了4月20日的一则重磅炸弹 。 Caitlin Dickerson写道:“自从10月份以来,已有超过700名儿童被成人自称为父母,其中包括100多名4岁以下的儿童。 现在是米里安。

然后,在5月15日的听证会上,参议员哈里斯向国土安全部负责人Kirstjen Nielsen提出了父母分居的答案,这在政治 出版物上引发了另一阵新闻报道。 最终,他们的交流将被NowThisPolitics打包成一个病毒视频,该视频在Facebook上分享超过7.7万次,但直到5月28日才会发布。
与此同时,亚利桑那共和国专栏作家EJ Montini突显了1,500名儿童的故事, 此后他的作品被“今日美国”杂志联合播出。这似乎是引发正义狂热的比赛。

当威斯康星州议会候选人凯茜迈耶斯将其发布到她的Facebook上时,这篇评论文章开始通过Reddit的r /政治渗透,然后通过自由世界起飞。 在Twitter上,前美国检察官Preet Bharara在Twitter上发表推文称:“在美国,边境婴幼儿的父母强行分离出什么更可耻的东西? 然后,失去这些孩子的踪迹?“它有8万个喜欢和超过26,000转推。

然而,值得注意的是,随着新闻周期通过互联网的众多心脏,它没有推动这个国家的分化。 事实上,已经出现了一个很大的共识: 三分之二的美国人不希望家庭分离继续下去 ,包括各种性别,种族,年龄和教育水平的多数群体。 所有的故事,推文,视频和照片的累积力量都是向心力的,让这个国家更接近一起。
这基本上是技术人员的梦想,最终在边界儿童的噩梦中找到了现实。


后记:
看到互联网,国外是Facebook/Twitter,在舆论上的“星火燎原”的力量,相比纸媒时代。相比下一开始就注重舆论监管/管控的政府,可谓未雨绸缪,技改一筹。
看看半互联网一代,原住民一代是如何在网络时代产生作用。
然而,需要反问的是,这些病毒式传播或迅速发酵的转发/评论/点赞/观点,有多少是经得起推敲和深度思考的?
2.
同样分享另一篇文章,也是跟Internet相关的,是twitter上,对Micrsoft口诛笔伐 过程被作者写的很精彩:
帮川普作恶,微软被围攻
https://mp.weixin.qq.com/s/9NgFiBtD-FBWymiIbZ-q4A

微软避锅大法
特朗普有甩锅大法,微软有避锅大法。他们表示坚决要和ICE的这些作为划清界限,但网友们依然不肯放过:
今年年初,你们可不是这么说的。
今年1月,微软Azure全球基础设施负责人Tom Keane在官方博客上发文,宣布微软Azure云服务拿下了美国空军和ICE的合同。博客中说,Azure会帮ICE处理敏感的未分类数据,还会帮他们运用深度学习来加速人脸识别和身份验证等。
ICE“正在为国土安全和公共安全部署革命性技术,我们很骄傲,可以用作为我们关键任务的云服务来支持这些工作。”Keane在一月的博客中态度很是明确:proud。
5月从Google离职的William Fitzgerald转发这条Twitter时,直接揪住这个“骄傲”质问微软CEO萨蒂亚·纳德拉(Satya Nadella):从妻离子散中赚钱,你骄傲?
随后,微软把博客里关于ICE的部分给删掉了。
这种欲盖弥彰的举动,引起了群众更大的反弹,也吸引媒体的兴趣。BuzzFeed、彭博社等多家媒体都报道了这一事件,也向微软询问了抹去信息的原因。
于是,这篇博客没过多久又恢复了原样。
微软的解释是:有个员工看见社交媒体上的评论之后暂时删除了博客内容,这是个错误行为,我们发现就把博客改回来了。
现在,微软对ICE的这些作为表示“惊诧”,还迫切希望这一部门改变政策,敦促国会通过保障儿童不再与家庭分离的法规,但丝毫没有表现出要退出项目不再续约的意思。
据彭博政府数据显示,微软和ICE的合同金额是1914万美元。


3.
Shops Aren’t for Shopping Anymore
Retail stores used to be places to buy things. Smartphones changed that, and retailers are struggling to invent new reasons, and methods, for shopping.
零售店曾经是购买物品的地方。 智能手机改变了这种状况,零售商正在努力发明新的理由和方法,以便购物。
这是不同于国内高新零售的玩法,国内像阿里/京东做的零售店,其实主题甚至内容不过依旧都是零售,体验似乎也只在虚拟换装/支付便利性等,就像在盒马基本上就是吃吃吃而已,看看看食物而已。
但文中所描绘的改变显然更进一步些。
4.
HBaseConWest2018演讲 - HBase Practice In XiaoMi
http://openinx.github.io/2018/06/18/hbaseconwest2018/

HBaseConWest2018于6.18日在美国加州圣何塞举办,本次会议由Hortonworks承办。每年去美国硅谷参加HBaseConWest已经算是小米HBase团队的惯例了,一方面小米团队在HBase社区的影响力有目共睹,目前已经培养了7位HBase Committer,其中有2位HBase PMC;另外一方面,小米内部也很乐意对外去分享公司一年所做的工作,相当于把一年的工作(包括内部的实践以及社区贡献)做一个年度总结分享给大家。
所以,2018年我们也很积极的提交了演讲议题(HBase Practice In XiaoMi),并花了很多精力整理总结,内部还做过3次英文试讲。但遗憾的是,今年中美关系比较紧张,美国签证没有如期办下来


5.
A Century in Wordclouds
想法很好,只可惜我对文中的结果存疑,但想法真的很好。
https://towardsdatascience.com/a-century-in-wordclouds-72be5f5ca391

###Tech

6.
使用JITWatch查看JVM的JIT编译代码
https://liuzhengyang.github.io/2017/07/27/jitwatch/
7.
OpenJDK commiter 的正确社交礼仪
不过从视频看,听众似乎不多
https://www.youtube.com/watch?v=mMvXcZV-2ZY
另一篇关于OpenJDK的
AdoptOpenJDK: Enhancing OpenJDK’s “build, test, contribute” pipeline
https://www.youtube.com/watch?v=d9HnAQAcfjQ
8.
Cloud Native Java, part deux, with Josh Long
话唠龙之春,看看开头对 cloud java的推崇;
https://www.youtube.com/watch?v=GW656IAU5ZE
9.
http://highscalability.com/blog/2018/6/15/stuff-the-internet-says-on-scalability-for-june-15th-2018.html
@taotetek: The goal of an observability team is not to collect logs, metrics or traces. It is to build a culture of engineering based on facts and feedback, and then spread that culture within the broader organization.
有点道理,鱼渔的观点
@tiffanycli: Reminder: When you give your DNA data to companies like http://Ancestry.com or 23andMe, you give up not only your own genetic privacy, but that of your entire family. (It’s in the terms & conditions.)
匹夫无罪,基因其罪
10.
一文读懂 Spark 和 Spark Streaming
https://ericfu.me/apache-spark-in-nutshell/
一般来说,想做到 fault-tolerance 只有两个方案:要么存储到外部(例如 HDFS),要么拷贝到多个副本。Spark 大胆地提出了第三种——重算一遍。但是之所以能做到这一点,是依赖于一个额外的假设:所有计算过程都是确定性的(deterministic)。Spark 借鉴了函数式编程思想,提出了 RDD(Resilient Distributed Datasets),译作“弹性分布式数据集”。
11.
很不错的分享:从头开始写一个日志采集Agent
日志采集中的关键技术分析
http://jm.taobao.org/2018/06/13/%E6%97%A5%E5%BF%97%E9%87%87%E9%9B%86%E4%B8%AD%E7%9A%84%E5%85%B3%E9%94%AE%E6%8A%80%E6%9C%AF%E5%88%86%E6%9E%90/
这里贴出一部分,非常建议去看原文,相信会有更多收获

如何发现一个文件?
定时去轮询下目录或许是个不错的方法,但是轮询的周期太长会导致不够实时,太短又会耗CPU,你也不希望你的采集Agent被人吐槽占用太多CPU吧。Linux内核给我们提供了高效的Inotify的机制,由内核来监测一个目录下文件的变化,然后通过事件的方式通知用户。但是别高兴的太早,Inotify并没有我们想的那么好,它存在一些问题,首先并不是所有的文件系统都支持Inotify,此外它不支持递归的目录监测
基于轮询的方式其优点就是保证不会漏掉文件,除非文件系统发生了bug,通过增大轮询的周期可以避免浪费CPU、但是实时性不够。Inotify虽然很高效,实时性很好但是不能保证100%不丢事件。因此通过结合轮询和Inotify后可以相互取长补短。
点位文件高可用
点位文件? 对就是通过点位文件来记录文件名和对应的采集位置。那如何保证这个点位文件可以可靠的写入呢? 因为可能在文件写入的那一刻机器Crash了导致点位数据丢掉或者数据错乱了。要解决这个问题就需要保证文件写入要么成功,要么失败,绝对不能出现写了一半的情况。Linux内核给我们提供了原子的rename。一个文件可以原子的rename成另外一个文件,利用这个特性可以保证点位文件的高可用。假设我们已经存在一份点位文件叫做offset,每一秒我们去更新这个点位文件,将采集的位置实时的记录在里面,整个更新的过程如下:
将点位数据写入到磁盘的offset.bak文件中
fdatasync确保数据写入到磁盘
通过rename系统调用将offset.bak更名为offset
通过这个手段可以保证在任何时刻点位文件都是正常的,因为每次写入都会先确保写入到临时文件是成功的,然后原子的进行替换。这样就保证了offset文件总是可用的。在极端场景下会导致1秒内的点位没有及时更新,日志采集Agent启动后会再次采集这1秒内的数据进行重发,这基本上满足需求了。

但是点位文件中记录了文件名和对应的采集位置这会带来另外一个问题,如果在进程Crash的过程中,文件被重命名了该怎么办?
Linux内核提供了inode可以作为文件的标识信息,而且保证同一时刻Inode是不会重复的,这样就可以解决上面的问题,在点位文件中记录文件的inode和采集的位置即可。日志采集Agent启动后通过文件发现找到要采集的文件,通过获取Inode然后从点位文件中查找对应的采集位置,最后接着后面继续采集即可。那么即使文件重命名了但是它的Inode不会变化,所以还是可以从点位文件中找到对应的采集位置。但是Inode有没有限制呢? 当然有,天下没有免费的午餐,不同的文件系统Inode会重复,一个机器可以安装多个文件系统,所以我们还需要通过dev(设备号)来进一步区分,所以点位文件中需要记录的就是dev、inode、offset三元组。到此为止我们的采集Agent可以正常的采集日志了,即使Crash了再次启动后仍然可以继续进行采集。但是突然有一天我们发现有两个文件居然是同一个Inode,Linux内核不是保证同一时刻不会重复的吗?难道是内核的bug?注意我用的是“同一时刻”,内核只能保证在同一时刻不会重复,这到底是什么意思呢? 这便是日志采集Agent中会遇到的一个比较大的技术挑战,如何准确的标识一个文件。

如何识别一个文件?
如何标识一个文件算是日志采集Agent中一个比较有挑战的技术问题了,我们先是通过文件名来识别,后来发现文件名并不可靠,而且还耗费资源,后来我们换成了dev+Inode,但是发现Inode只能保证同一时刻Inode不重复,那这句话到底是什么意思呢? 想象一下在T1时刻有一个文件Inode是1我们发现了并开始采集,一段时间后这个文件被删除了,Linux内核就会将这个Inode释放掉,新创建一个文件后Linux内核会将刚释放的Inode又分配给这个新文件。那么这个新文件被发现后会从点位文件中查询上次采集到哪了,结果就会找到之前的那个文件记录的点位了,导致新文件是从一个错误的位置进行采集。如果能给每一个文件打上一个唯一标识或许就可以解决这个问题,幸好Linux内核给文件系统提供了扩展属性xattr,我们可以给每一个文件生成唯一标识记录在点位文件中,如果文件被删除了,然后创建一个新的文件即使Inode相同,但是文件标识不一样,日志采集Agent就可以识别出来这是两个文件了

如何知道文件内容更新了?
Inotify可以解决这个问题、通过Inotify监控一个文件,那么只要这个文件有新增数据就会触发事件,得到事件后就可以继续采集了。但是这个方案存在一个问题就是在大量文件写入的场景会导致事件队列溢出,比如用户连续写入日志N次就会产生N个事件,其实对于日志采集Agent只要知道内容就更新就可以了,至于更新几次这个反而不重要, 因为每次采集其实都是持续读文件,直到EOF,只要用户是连续写日志,那么就会一直采集下去。另外Intofy能监控的文件数量也是有上限的。所以这里最简单通用的方案就是轮询去查询要采集文件的stat信息,发现文件内容有更新就采集,采集完成后再触发下一次的轮询,既简单又通用
如何安全的释放文件句柄?
Fluentd的处理方式就是将这部分的责任推给用户,让用户配置一个时间,文件删除后如果在指定的时间范围内没有数据新增就释放fd,其实这就是间接的甩锅行为了。这个时间配置的太小会造成丢数据的概率增大,这个时间配置的太大会导致fd和磁盘空间一直被占用造成短时间自由浪费的假象


12.
阿里巴巴为什么不用 ZooKeeper 做服务发现?
http://jm.taobao.org/2018/06/13/%E5%81%9A%E6%9C%8D%E5%8A%A1%E5%8F%91%E7%8E%B0%EF%BC%9F/
作者其实讨论的是关于服务配置/服务发现/服务状态,这些当然目前也没听说有同时实现。。。
这里贴出一部分,非常建议去看原文,相信会有更多收获.

注册中心是 CP 还是 AP 系统?
CAP 和 BASE 理论相信读者都已经耳熟能详,其业已成了指导分布式系统及互联网应用构建的关键原则之一,在此不再赘述其理论,我们直接进入对注册中心的数据一致性和可用性需求的分析:
数据一致性需求分析?
分区容忍及可用性需求分析?:
接下来我们看一下网络分区(Network Partition)情况下注册中心不可用对服务调用产生的影响,即 CAP 中的A不满足时带来的影响。
当机房3出现网络分区(Network Partitioned)的时候,即机房3在网络上成了孤岛,我们知道虽然整体 ZooKeeper 服务是可用的,但是节点ZK5是不可写的,因为联系不上 Leader。
也就是说,这时候机房3的应用服务 svcB 是不可以新部署,重新启动,扩容或者缩容的,但是站在网络和服务调用的角度看,机房3的 svcA 虽然无法调用机房1和机房2的 svcB,但是与机房3的svcB之间的网络明明是 OK 的啊,为什么不让我调用本机房的服务?
现在因为注册中心自身为了保脑裂(P)下的数据一致性(C)而放弃了可用性,导致了同机房的服务之间出现了无法调用,这是绝对不允许的!可以说在实践中,注册中心不能因为自身的任何原因破坏服务之间本身的可连通性,这是注册中心设计应该遵循的铁律! 后面在注册中心客户端灾容上我们还会继续讨论。
同时我们再考虑一下这种情况下的数据不一致性,如果机房1,2,3之间都成了孤岛,那么如果每个机房的svcA都只拿到本机房的 svcB 的ip列表,也即在各机房svcB 的ip列表数据完全不一致,影响是什么?
其实没啥大影响,只是这种情况下,全都变成了同机房调用,我们在设计注册中心的时候,有时候甚至会主动利用这种注册中心的数据可以不一致性,来帮助应用主动做到同机房调用,从而优化服务调用链路 RT 的效果!
注册中心需要持久存储和事务日志么?
需要,也不需要。
我们知道 ZooKeeper 的 ZAB 协议对每一个写请求,会在每个ZooKeeper节点上保持写一个事务日志,同时再加上定期的将内存数据镜像(Snapshot)到磁盘来保证数据的一致性和持久性,以及宕机之后的数据可恢复,这是非常好的特性,但是我们要问,在服务发现场景中,其最核心的数据-实时的健康的服务的地址列表真的需要数据持久化么?
Service Health Check
使用 ZooKeeper 作为服务注册中心时,服务的健康检测常利用 ZooKeeper 的 Session 活性 Track机制 以及结合 Ephemeral ZNode的机制,简单而言,就是将服务的健康监测绑定在了 ZooKeeper 对于 Session 的健康监测上,或者说绑定在TCP长链接活性探测上了。
这在很多时候也会造成致命的问题,ZK 与服务提供者机器之间的TCP长链接活性探测正常的时候,该服务就是健康的么?答案当然是否定的!注册中心应该提供更丰富的健康监测方案,服务的健康与否的逻辑应该开放给服务提供方自己定义,而不是一刀切搞成了 TCP 活性检测!
我们在阿里巴巴内部应用接入 ZooKeeper 时,有一个《ZooKeeper 应用接入必知必会》的 WIKI,其中关于异常处理有过如下的论述:


13.
如上,不错的zookeeper踩坑分享
采用zookeeper的EPHEMERAL节点机制实现服务集群的陷阱
https://yq.aliyun.com/articles/227260

1、不处理zk的连接状态变化事件导致zk客户端断开后与zk服务器集群没有重连。后果:连接丢失后EPHEMERAL节点会删除并且客户端watch丢失。
2、在synconnected事件中创建EPHEMERAL节点没有判断此节点是否已经存在,在已经存在的情况下没有判断是否应该删除重建,后果:EPHEMERAL节点丢失导致可用的服务器不在可用服务器列表中。
3、应用程序关闭时不主动关闭zk客户端,后果:导致可用服务器列表包含已经失效的服务器。
4、创建一个zk客户端时,zk客户端连接zk服务器是异步的,如果在连接还没有建立时就调用zk客户端会抛异常。
5、在zk的事件中执行长时间的业务
6、使用2.X版本的Curator时,ExponentialBackoffRetry的maxRetries参数设置的再大都会被限制到29:MAX_RETRIES_LIMIT。


14.
很不错的总结
实时数据的可视化
http://icodeit.org/2018/06/real-time-data-visualization/
15.
Theranos founder Elizabeth Holmes may be our first true feminist anti-hero
https://work.qz.com/1285831/theranos-founder-elizabeth-holmes-may-be-our-first-true-feminist-anti-hero/
16.
How to prevent logback from outputting its own status at the start of every log?
https://stackoverflow.com/questions/3257154/how-to-prevent-logback-from-outputting-its-own-status-at-the-start-of-every-log
如何让logback不输出自己的status信息,诸如在启动logback时的:“11:21:27,825 |-INFO in ch.qos.logback…”信息?

If you have any configuration problems of level WARN or above, you will also get all status information logged to the console (including messages of level INFO). The best solution to this problem is to fix the problem (in your case replace the element with an element).
If you for some reason cannot fix the problem, but want to remove the status-information from the console, you can instead configure an alternative StatusListener. Use the NopStatusListener to completely remove the status-information:


1
2
3
4
<configuration>
<statusListener class="ch.qos.logback.core.status.NopStatusListener" />
<!-- etc -->
</configuration>

17.
https://blog.softwaremill.com/scalaz-8-io-vs-akka-typed-actors-vs-monix-part-1-5672657169e1
18.
Meet the New Logstash Java Execution Engine
https://www.elastic.co/blog/meet-the-new-logstash-java-execution-engine
新版Logstash采用Java Execution Engine,大大提升性能
19.
http://arganzheng.life/ai-infrastructures-from-big-data-to-deep-learning.html
20.
github上上周一个 pop 项目
https://github.com/danistefanovic/build-your-own-x
21.
https://github.com/pod4g/hiper
22.
https://medium.com/observability/microservices-observability-26a8b7056bb4
23.

From the Hotspot JVM source code, we can see the following GC roots types:


1
2
3
4
5
6
7
8
9
10
11
enum RootType {
universe = 1,
jni_handles = 2,
threads = 3,
object_synchronizer = 4,
system_dictionary = 5,
class_loader_data = 6,
management = 7,
jvmti = 8,
code_cache = 9
};

And from comment of source code, we can conclude the meaning of those roots:
Universe: is a name space holding known system classes and objects in the VM. The object heap is allocated and accessed through Universe, and various allocation support is provided.
JNIHandles: JNI code
Threads: live threads
ObjectSynchronizer: monitor object
Management: JVM used management class
JvmtiExport: JVM tool interface, for debug & profiling;
SystemDictionary: Loaded classes are accessible through the SystemDictionary.
ClassLoaderDataGraph: A class loader represents a linkset. Conceptually, a linkset identifies the complete transitive closure of resolved links that a dynamic linker can produce. A ClassLoaderData also encapsulates the allocation space, called a metaspace, used by the dynamic linker to allocate the runtime representation of all the types it defines.