<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>架构 on 涯余的博客</title><link>https://hangyan.github.io/tags/%E6%9E%B6%E6%9E%84/</link><description>Recent content in 架构 on 涯余的博客</description><generator>Hugo</generator><language>zh</language><managingEditor>hang.yan@hotmail.com (涯余)</managingEditor><webMaster>hang.yan@hotmail.com (涯余)</webMaster><lastBuildDate>Sat, 31 Aug 2019 13:35:37 +0000</lastBuildDate><atom:link href="https://hangyan.github.io/tags/%E6%9E%B6%E6%9E%84/index.xml" rel="self" type="application/rss+xml"/><item><title>失败博物馆 - Hadoop</title><link>https://hangyan.github.io/post/2019-08-31-hadoop/</link><pubDate>Sat, 31 Aug 2019 13:35:37 +0000</pubDate><author>hang.yan@hotmail.com (涯余)</author><guid>https://hangyan.github.io/post/2019-08-31-hadoop/</guid><description>&lt;p&gt;Hadoop 严格来说并不算完全失败了，不像 Mesos 那样，而是人们期待它成为一个大象， 而它却变成了一只兔子。&lt;/p&gt;
&lt;p&gt;我刚毕业就开始接触Hadoop, 当时它基本上就是大数据的代名词。在这个光辉的表象之下，研发人原面临的是一个非常不透明，UI丑陋，运行缓慢的系统。当然，技术的狂热周期会让人放弃自己的疑虑，专心地去这座 &lt;code&gt;shit mountain&lt;/code&gt; 扒拉东西。另外，也没得选。&lt;/p&gt;
&lt;p&gt;同样的情况也发生在 Jenkins, Mesos 身上，当没有对比的时候，人们很难意识到自己面对的东西的优缺点是什么。时至今日，在吃尽了很多苦头之外，我们可以回过头来想想，为什么有的软件成功了？为什么有的失败了？&lt;/p&gt;
&lt;p&gt;成功的特性几乎是不言自明的，我们可以列举如下：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;模块化 / 可扩展性好&lt;/li&gt;
&lt;li&gt;接口用户友好 (页面，编程语言，API)&lt;/li&gt;
&lt;li&gt;文档全面&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这些就够了。而失败软件在每一方面，几乎都没做好。Hadoop 也是如此。&lt;/p&gt;
&lt;p&gt;同时因为这些因素存在，人们从最初的狂热清醒下来之后，便开始想尽一切办法找寻可能的替代品。在数据量不大的时候尽量选择其他工具(pandas, unix tools等等)， Spark, Hive, Pig&amp;hellip;. 甚至连 Hadoop 第二代的 YARN 都被 Kubernetes 无意打残了。当然，这个现状有一个比较好的词叫&lt;code&gt;生态圈&lt;/code&gt;，但它和 Kuberentes 的生态圈还是很不同的。前者是因为太难用，被肢解，被不断替代。后者是根系稳固，枝叶繁茂。（没写完，待补。）&lt;/p&gt;
&lt;h2 id="links"&gt;Links&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href="https://architecht.io/what-happened-to-hadoop-211aa52a297"&gt;What happened to Hadoop&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.chrisstucchio.com/blog/2013/hadoop_hatred.html"&gt;Don&amp;rsquo;t use Hadoop - your data isn&amp;rsquo;t that big&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://adamdrake.com/command-line-tools-can-be-235x-faster-than-your-hadoop-cluster.html"&gt;Command-line Tools can be 235x Faster than your Hadoop Cluster&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/pachyderm-data/lets-build-a-modern-hadoop-4fc160f8d74f"&gt;Let’s build a modern Hadoop&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.zhihu.com/question/26568496"&gt;与 Hadoop 对比，如何看待 Spark 技术？&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://zhuanlan.zhihu.com/p/76829123"&gt;Hadoop再凉凉，前大数据独角兽公司MapR被惠普企业（HPE）收购&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://zhuanlan.zhihu.com/p/71139401"&gt;驳「Hadoop 快不行了」&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://zhuanlan.zhihu.com/p/70586829"&gt;Hadoop 不再权威，开源大数据的未来何去何从？&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://computerrepairkansascity.typepad.com/blog/2012/06/the-dark-side-of-hadoop.html"&gt;The dark side of Hadoop&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;</description></item><item><title>失败博物馆 - Mesos/Marathon</title><link>https://hangyan.github.io/post/2019-08-23-mesos-marathon/</link><pubDate>Fri, 23 Aug 2019 10:28:40 +0000</pubDate><author>hang.yan@hotmail.com (涯余)</author><guid>https://hangyan.github.io/post/2019-08-23-mesos-marathon/</guid><description>&lt;p&gt;Mesos/Marathon 的失败，怎么说，太过典型了。如教科书一般，清晰的不能再清晰。&lt;/p&gt;
&lt;p&gt;首先，它流行的时候，是因为大家没得选。一个还在蹒跚学步阶段的 Kubernetes 就开始将它打的节节败退。到了现在，连Mesosphere 已经转向了 Kubernetes。&lt;/p&gt;
&lt;p&gt;从一开始，这就是一个学术界的产品。由一堆并不擅长编写工业化软件的研究室的学生和老师写出。这导致了 Mesos / Marathon 的致命缺陷&lt;/p&gt;
&lt;p&gt;首先，用 C++ 写 Mesos， C++可以说是学术界和工业界态度差别最大的编程语言了。对学术界来说，这是一个可以用来探究编程语言极限的编程语言，数不清的高级设计，数不清的语言学设计，你再任何其他语言里都见不到这么博大精深的体系。但对工业界来说，这是一种灾难级的编程语言。Linux 都在天天骂它，难学难用难调试，市场占有率也一直不断下滑。Mesos 选择了 C++之后，极大地减少了开源社区去贡献代码的可能性，彻底沦为了创世的开发团队自己的作品。&lt;/p&gt;
&lt;p&gt;更灾难的是，Marathon 用了 Scala，一个除了 C++之外第二复杂的语言。其同样程度的撕裂性，对研发人员的折磨，让人都开始怀疑为什么当初要选择编程这份工作。语言设计者一旦觉得自己过于聪明，会趋向出设计出来大众难以理解的东西。这并不怪大众，而是怪语言设计者。两个世界上最复杂的语言，组合起来，成了一个大部分研发人员都不愿意碰的黑盒子。然而，它又不是稳定到不出什么问题，总会有出故障需要排查的时候。这便是让所有人都痛苦的时刻。所以即使今天大家发现 Kubernetes 已经非常复杂难以理解了，但没有人会抱怨太多，因为只要你肯花点时间，分析分析代码，总能慢慢理解。而对于 Mesos/Marathon,如果你发现了一个问题，想去阅读代码，大部分时间你都在纠结：这个语法什么意思？这个语法又是什么意思？&lt;/p&gt;
&lt;p&gt;另外一种研究室出来的代码的问题在于，很少有人会考虑到架构的可扩展性。有了一个 idea,实现出来，发个 paper，大部分就完了。等到真正开始用户多的时候已经来不及了。而工业界的产品不一样，从一开始可扩展性就是所有系统在设计之初必须考虑的一个问题。所以我们看到，Mesos/Marathon 自发布之后，后续的功能扩充是极其微弱的，难以有任何实质性的功能增强。而 Kubernetes 在发布之后，新功能如井喷一般。当然这里面也有编程语言本身的功能。Golang 问题再多，简单易用本身就足够让很多人开始使用了。&lt;/p&gt;</description></item><item><title>失败博物馆 - Jenkins</title><link>https://hangyan.github.io/post/2019-08-22-fuck-jenkins/</link><pubDate>Thu, 22 Aug 2019 17:02:37 +0000</pubDate><author>hang.yan@hotmail.com (涯余)</author><guid>https://hangyan.github.io/post/2019-08-22-fuck-jenkins/</guid><description>&lt;p&gt;我想记录一下工作中使用过的软件里的一些在设计上比较失败的。因为它们，工作中多了很多痛苦。&lt;/p&gt;
&lt;p&gt;Jenkins 便是其中之一。跟很多软件一样，Jenkins 在商业上是成功的，成功的原因就是用户并没有什么选择。对 Jenkins 非常了解的人来说，能很容易列举出非常多的详细的jenkins 的问题。从一个普通使用者的角度来看，最直观的两个感觉就是: Jenkinsfile 难写，流水线很慢。&lt;/p&gt;
&lt;p&gt;对我来讲，Jenkinsfile 就是最大的设计败笔。从工作中的反馈来看，即使看了文档，也没人知道怎么去写一个正确的 Jenkinsfile。用户想描述好一些流水线步骤，最直观的想法应该就是贴近于 Makefile, 每个步骤几条命令，清清楚楚。再加上其他一些并发控制，产出物管理即可。用 YAML 或者 TOML 这样的配置文件即可。&lt;/p&gt;
&lt;p&gt;几乎除了 Jenkins 之外的所有 CI/CD 工具，都选择了 用YAML。而 Jenkins 使用了 Jenkinsfile, Groovy 语言，意味着用户需要首先了解 Groovy，在学习 jenkins的语法，才能写好 Jenkinsfile。一些自作聪明的开发人员在类似的设计问题时，会有一种炫技的想法，总想用 DSL 来解决问题。结果通常是不好的，既给用户带来了沉重的负担，也让系统变得难以理解。基于 JVM 的很多语言都是如此命运。&lt;/p&gt;
&lt;p&gt;即使你费劲千辛万苦，终于写出了一个能跑通的 Jenkinsfile,这时候你会发现，在 Jenkins 的流水线里面，有很多复杂的难以理解的东西。为什么多出来很多莫名其妙的步骤？系统日志和构建日志怎么这么杂乱无章地堆在一块？为什么速度总是这么慢？界面为什么这么丑？不一而足。&lt;/p&gt;
&lt;p&gt;想深刻地理解这些问题在哪，当然可以去好好探究一下它的架构，然后了解这些问题的根源。但这是在没有必要了，对于一个将死的系统来说。作为用户来讲，在已经有了替代品之后，赶快逃离就是了。&lt;/p&gt;</description></item><item><title>少有人用的 debugger</title><link>https://hangyan.github.io/post/2019-05-06-debugger/</link><pubDate>Mon, 06 May 2019 11:32:22 +0000</pubDate><author>hang.yan@hotmail.com (涯余)</author><guid>https://hangyan.github.io/post/2019-05-06-debugger/</guid><description>&lt;p&gt;不知道别人是怎么认为的，我之前一直认为，Debugger 应该是一个正统的解决软件问题的方式。我们应该尽力地去多用这种方式，通过各种其他的 print 等方式是一种原始的，偷懒的，笨拙的方法。&lt;/p&gt;
&lt;p&gt;我也总是去尝试学习各种 debugger 以及在工作中去使用它们，但都是很难进行下去。真实的工作场景中也鲜有人用 debugger。是大家都在逃避问题，投机取巧吗？&lt;/p&gt;
&lt;p&gt;今天看的几篇文章让我明白了，debugger 并不是什么正统，而是一种适用范围非常狭窄，应该尽量少用的方式。用 print 之类的&lt;code&gt;笨办法&lt;/code&gt;是应该的，值得推荐的。&lt;/p&gt;
&lt;p&gt;Linux 在邮件列表里表达的对于在内核开发中使用 debugger 的看法也很适用于通用软件的场景:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;It&amp;#39;s partly &amp;#34;source vs binary&amp;#34;, but it&amp;#39;s more than that. It&amp;#39;s not that you
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;have to look at the sources (of course you have to - and any good debugger
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;will make that _easy_). It&amp;#39;s that you have to look at the level _above_
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sources. At the meaning of things. Without a debugger, you basically have
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;to go the next step: understand what the program does. Not just that
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;particular line.
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;相对来说，debugger 本身更像是对问题的逃避，我们放弃对于问题以及代码更为细致的观察与思索，直接交给程序来一行一行校验代码的正确性。而在没有 debugger 的场景下，我们需要花费更多的时间来思考整个程序的设计，自上而下地考量整个问题以及解决的方式对不对，最终的困惑可以通过 print/system tools 等工具结合起来去校验。通过这种方式，最终对问题的解决可能并不是对于现有某些代码的修改，而是对于代码整体的重构与调整。&lt;/p&gt;</description></item><item><title>jekyll 的问题</title><link>https://hangyan.github.io/post/2019-05-05-jekyll/</link><pubDate>Sun, 05 May 2019 13:14:29 +0000</pubDate><author>hang.yan@hotmail.com (涯余)</author><guid>https://hangyan.github.io/post/2019-05-05-jekyll/</guid><description>&lt;!-- toc --&gt;
&lt;p&gt;考虑良久，决定将 Blog 迁移到 hexo。整个过程比想象的简单很多，也看了下二者的异同。相对于来讲，我觉得 hexo 在设计上比 jekyll 更为优良一些，更适合作为一个静态博客生成器。
那么，jekyll 的问题在哪?&lt;/p&gt;
&lt;h2 id="目录结构"&gt;目录结构&lt;/h2&gt;
&lt;p&gt;jekyll 的目录结构是 posts/themes/settings 等杂糅在一起，初看起来更好理解，但使用起来是很痛苦的。尤其是在更换 theme 的时候，需要小心翼翼地甄别哪些目录需要更换而哪些不需要。而 hexo 的目录结构更加清晰，每个 themes 的内容都包含在一个单独的目录中，与其他部分互不干扰。想要更换 theme 直接 clone 一个新的改一个配置参数即可。&lt;/p&gt;
&lt;p&gt;更换 theme 的次数越多，jekyll 的目录结构会越来越乱，分不清哪些文件是当前必须的。而 hexo 没这个问题。&lt;/p&gt;
&lt;h2 id="默认主题"&gt;默认主题&lt;/h2&gt;
&lt;p&gt;jekyll 没有默认主题。或者说有，但大家不这样用。通常的用法都是找一个现成的第三方 blog clone 下来，然后按自己的需求改。这样有个问题就是，总会有一种不适配的感觉。因为主题都是别人为自己的使用配置的。而 hexo 提供了默认的主题，它是这个软件自带的一部分，是理所应当的&lt;code&gt;属于&lt;/code&gt;我们自身的。而且这个默认的主题已经足够好用，同时第三方的&lt;code&gt;next&lt;/code&gt;主题也占据了相当大的份额。不是说选择少，而是在 hexo 上能够更快地完成&lt;code&gt;theme&lt;/code&gt;配置这一环而专注于内容。&lt;/p&gt;
&lt;h2 id="功能"&gt;功能&lt;/h2&gt;
&lt;p&gt;jekyll 各个 theme 的功能丰富程度差别很大，分页、评论、TAG 等等。不同主题想要添加新功能的方式不同，遇到问题处理的简易程度也不一样。而这种情况也往往导致用户会选择更换主题，然后继续恶性循环。hexo 的默认主题提供了对大多数常用功能的支持，而扩充起来也比较方便，不同主题在这块的差别也比较小。&lt;/p&gt;
&lt;h2 id="内容发布"&gt;内容发布&lt;/h2&gt;
&lt;p&gt;这块 jekyll 完全没做，必须得自己手动创建 md，添加头部的 attribute,之前还借鉴了其他人的 shell 脚本来根据模板自动生成这些内容。而 hexo 提供了&lt;code&gt;new&lt;/code&gt;命令来创建新的 post,自动补上头部的内容，这样学习成本基本上就只剩 markdown 了。&lt;/p&gt;
&lt;p&gt;目前静态博客软件的内容发布还是太偏程序员化了，可以参考 wordpress 的地方还有很多。目前已经有一些 admin 页面的项目流行起来，但还没有达到能让普通用户无学习成本使用的程度。&lt;/p&gt;
&lt;h2 id="其他"&gt;其他&lt;/h2&gt;
&lt;p&gt;目前静态博客的分化是好事，但有点像 linux distros 那样，最终也带来了很多恶性循环。大家不关注易用性去普及用户，而更关注彼此设计理念的不同。一堆程序员圈地自嗨，最终可能只是落得自娱自乐罢了。&lt;/p&gt;</description></item><item><title>Kubernetes 笔记</title><link>https://hangyan.github.io/post/2017-08-18-kubernetes-note/</link><pubDate>Fri, 18 Aug 2017 00:00:00 +0000</pubDate><author>hang.yan@hotmail.com (涯余)</author><guid>https://hangyan.github.io/post/2017-08-18-kubernetes-note/</guid><description>&lt;!-- toc --&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://hangyan.github.io/post/2017-08-18-kubernetes-note/#api"&gt;API&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://hangyan.github.io/post/2017-08-18-kubernetes-note/#%e5%a3%b0%e6%98%8e%e5%bc%8f%e7%9a%84-api"&gt;声明式的 API&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://hangyan.github.io/post/2017-08-18-kubernetes-note/#api-response"&gt;API Response&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://hangyan.github.io/post/2017-08-18-kubernetes-note/#%e9%94%99%e8%af%af%e5%a4%84%e7%90%86"&gt;错误处理&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://hangyan.github.io/post/2017-08-18-kubernetes-note/#resource-version"&gt;Resource Version&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://hangyan.github.io/post/2017-08-18-kubernetes-note/#version"&gt;Version&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://hangyan.github.io/post/2017-08-18-kubernetes-note/#api-group"&gt;API Group&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://hangyan.github.io/post/2017-08-18-kubernetes-note/#runtime-config"&gt;Runtime config&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://hangyan.github.io/post/2017-08-18-kubernetes-note/#regex"&gt;REGEX&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://hangyan.github.io/post/2017-08-18-kubernetes-note/#%e5%ad%97%e6%ae%b5%e6%a0%bc%e5%bc%8f"&gt;字段格式&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://hangyan.github.io/post/2017-08-18-kubernetes-note/#patch-%e4%b8%8e-put"&gt;PATCH 与 PUT&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://hangyan.github.io/post/2017-08-18-kubernetes-note/#events"&gt;Events&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://hangyan.github.io/post/2017-08-18-kubernetes-note/#%e4%ba%a4%e4%ba%92"&gt;交互&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://hangyan.github.io/post/2017-08-18-kubernetes-note/#%e8%be%93%e5%87%ba"&gt;输出&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://hangyan.github.io/post/2017-08-18-kubernetes-note/#%e8%be%93%e5%85%a5"&gt;输入&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;!-- tocstop --&gt;
&lt;h1 id="api"&gt;API&lt;/h1&gt;
&lt;h2 id="声明式的-api"&gt;声明式的 API&lt;/h2&gt;
&lt;p&gt;声明式： 结果是什么
命令式: 做什么&lt;/p&gt;
&lt;p&gt;声明式的操作，相对于命令式操作，对于重复操作的效果是稳定的，这对于容易出现数据丢失或重复的分布式环境来说是很重要的。另外，声明式操作更容易被用户使用，可以使系统向用户隐藏实现的细节，隐藏实现的细节的同时，也就保留了系统未来持续优化的可能性&lt;/p&gt;
&lt;p&gt;kubernetes 里的 API 都是声明式,我们描述好自己想要的 resource object,kubernetes 就会不断尝试去保证这个 resource object 按我们期望的方式存在.&lt;/p&gt;
&lt;h2 id="api-response"&gt;API Response&lt;/h2&gt;
&lt;p&gt;一般包含三部分&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;metadata: 元数据
&lt;ul&gt;
&lt;li&gt;annotations: 一些元信息.给第工具用来存储和解析原信息用的.&lt;/li&gt;
&lt;li&gt;labels: act as filter&lt;/li&gt;
&lt;li&gt;namespace: resource 所处的 namespace&lt;/li&gt;
&lt;li&gt;name: resource 名字&lt;/li&gt;
&lt;li&gt;uuid: 唯一标识&lt;/li&gt;
&lt;li&gt;creationTimestamp: 创建时间&lt;/li&gt;
&lt;li&gt;deletionTimestamp: 计划删除的时间(graceful deletion)&lt;/li&gt;
&lt;li&gt;resourceVersion: 每个 resource 的内部版本,可以用来确定是否发生了变化.也用于做并发控制&lt;/li&gt;
&lt;li&gt;generation&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;spec: 具体描述,不同 resource 的属性不同。spec 里通过声明式的方式表明了期望的目标状态&lt;/li&gt;
&lt;li&gt;status: resource 的当前状态&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;下面以展示一下 kubernetes node api 的 metadata 作为样例:&lt;/p&gt;</description></item></channel></rss>