《时间的玫瑰》投资阅读笔记

最近读完了但斌的《时间的玫瑰》,作为一本投资理财相关的笔记书籍。先摘录一些笔记,然后是个人的一些感悟。 笔记摘要 ◆ 序一 价值投资的完美践行者 价值投资有且只有4个核心理念,这4个核心理念堪称简单、完美: 1.股票是对公司的部分所有权。 2.市场只会告诉你价格是什么,而不会告诉你价值是什么。 3.投资本质上是对未来进行预测,预测结果不可能100%正确,因此要有安全边际,安全边际主要源自买得便宜和低预期。 4.通过长时间的努力可以形成自己的能力圈,能力圈的边界比大小重要。 ◆ 中国私人财富管理 土地是经济发展的函数,经济发展了,其成果最终一定要反映到地价上,整个经济发展一定会在固定资产中得到不断体现。 再说房地产调控,目前的调控我的理解是国家实际上在帮助央企、龙头型企业消除其竞争对手。另外,行业龙头企业的诞生,一定是在行业处于困境的情况下,如果都赚钱了,谁也不会破产不会转卖。 ◆ 穿越时间的河流与伟大企业共成长 在我们的价值体系和哲学思考中,我们认为,只有从企业本身出发,才能真正赚到钱,这也是我们东方港湾成立以来一直在学习和坚持的东西。 ◆ 投资札记之一:偶然的投资人生 发现优秀企业,趁低购买,长期持有(BUY AND HOLD IT)”的策略是目前为止被证明是最有效的投资方法!“成长型价值投资法”是我们罗盘上指向北极的唯一指针。 简而言之,我们希望选择的企业符合几项标准: 有长期稳定的经营历史; 有高度的竞争壁垒,甚至是垄断型企业,最好是非政府管制型垄断; 管理者理性、诚信,以股东利益为重; 财务稳健,负债不高而净资产收益率高,自由现金流充裕; 我们能够理解的,能够把握的企业。 作为投资人,应该更多地研究企业经营,简单称为“产、供、销”几方面,只有经营得好的企业,才有投资价值。 我们 那么何时卖出呢?理论上讲,好企业最好长期持有,但以下三种情况我们也会选择卖出: 好企业被市场高估太多了。 好企业开始衰退期。 当我们发现更好的企业,更换旧的投资。 ◆ 投资札记之二:选股没有秘密 招商银行的未来 没有事物是永恒的,招商银行也一样无法确定自己的未来。但有一点是肯定的,只要有人类存在,银行业就会一直发展下去。某种意义上,“银行业的未来就是人类社会的未来”(见亨利·英格勒、詹姆斯·埃森格《银行业的未来》)。 越有能力的人越渴望自由,而平均水准以下的人群渴望的则是公平。 ◆ 投资札记之三:投资最难的是什么 如果我们不愿意拥有一家股票十年,那就不要考虑拥有它十分钟。”这是巴菲特选择企业的原则。 ◆ 投资札记之四:给新股民的建议 许多投资者在计算他们的财富时,记忆永远停留在他们曾经达到的最辉煌的那一刻,常将某一天的最高市值视为已到手的收益,然后以那一刻的市值来计算他的得失。结果,变化的市值与最高市值相比,难免心态失衡。投资应该超越这种“财富观”。过去的市值包括买入价格等都属于“沉没成本”。有的人天天看自己账户上市值的变化,其实这没有任何意义,更容易唤起一种心里错觉,患得患失 ◆ 投资札记之五:股市知与行 西方有一句古老的谚语:要为长期而买进!时间是最有价值的资产,我们今天所买入的股票不仅仅属于我们自己,还是整个家族的。我们应该为我们的子孙担负起此刻的职责。 ,全世界只有少数国家或地区允许赌博业合法,因为它是一个你赢我输的零和游戏。但资本市场为什么在这么多国家获得支持和发展,其实它的本质是非零和游戏,是参与者能共赢的游戏。 ◆ 坚持是价值投资的核心 《证券市场周刊》:你认为价值投资理论复杂吗?但斌:很简单。巴菲特提到价值投资观念的核心是“以40美分的价格买进一美元的纸钞”,而成长是优秀公司价值的一个必要组成,即是说,这个一美元的纸钞随着时间仍在继续增值。这个方法本身不是很难,很容易讲明白,但是坚持不容易。这里面我认为存在三个无法避过的阶段:一是理解和接受价值投资的观念;二是要本着严谨的态度,以逻辑合理的方法去评估企业的价值;三是在动荡的环境中坚持。规则很简单,但是坚持太难了。 我们对组合理论的理解,大概7个股票是最好的结果,超出了可能很难达到最大的收益,降低了可能风险就稍微大一点。好股就那么多。一个经济体中,企业的构成像金字塔,最好的企业就是塔尖那么几个,越往下越差。你的资金越集中在金字塔的顶部,收益越高。 证券市场周刊》:那你讲一下他的财富观。但斌:就是说你对财富是怎么看待的。比如说一般的老百姓说我有钱了,要买好车,要买好房子,娶个好老婆。但是财富就是改变世界、影响世界的工具,就是这个财富应该被谁驾驭,这是一个社会问题。假设有上帝,上帝会进行选择,他会选择把这些财富交给什么样的人来管理,这是很重要的。为什么中国的富豪老出事呢?就是这个人如果不义,上帝也不会把更多的财富给他。 资本市场的本质是什么?就把社会财富放到最有效率的一个企业里,让最能干的人、最好的团队、有最好文化的企业来运用。把财富交到这些人手里,然后让他们去创造财富。巴菲特做的事情就是把钱放到这些好企业里。 ◆ 价值投资的内在逻辑 但斌:熊市的时候有很多股票可以挑,打个比喻,就像打高尔夫球一样,很多球都落在地上,可以不断地打,打飞一个以后还有。熊市里,如果错过茅台还有招商银行,错过招商银行还有万科。现在是打一个少一个,快打光了。很多人“5·30”空仓了,他想球还会落在地上,还会让他有一个合适的位置打,但是恰恰相反,他想买的东西不断往上涨,他不想买的东西不断往下跌,他没有球可打。更可怕的是,如果他认为这些股票高估的假设是成立的,也许还能够等到这个球,如果事情的发展超出他的想象,真的连续3年100%增长,这个球就永远打不到了。如果思维方式不变,或者是对于这个增长老是持怀疑态度,他永远打不着这个球。所以投资难在哪?长期投资坚持的是什么?是对于一个国家、一个企业,它长期发展的逻辑有没有一个合理判断,有了这样一个合理的判断,你才有机会打出好球,否则的话会很遗憾。 ◆ 价值投资的本质是什么? 但斌:高盈利行业的共同特征是商业模式简单、可靠,容易理解,有强大的商业壁垒,有持续创造财富的能力。 我们自己算过,未来七年,茅台每年会有21%~24%的复合增长。腾讯我们现在看不到天花板,但是我们觉得它会大得像一个国家一样,不排除到10万亿元的可能性。 有些人后悔不过是因为他们不停在变。 ◆ 纽约上空自由飞翔的鸽子 女神像底座上的诗歌“欢迎你,那些疲乏了的和贫困的挤在一起渴望自由呼吸的大众,那熙熙攘攘的被遗弃了的可怜的人们。把这些无家可归的饱受颠沛的人们一起交给我。我站在金门口,高举起自由的灯火!”为理想的国家而言,显然是历史的倒退……美国的价值观已经在“撕裂”…… ◆ 绽放我们的生命 此刻,这位老朋友也让我联想起英国圣公会主教墓碑上的一段话:当我年轻自由的时候,我的想象力没有任何局限,我梦想改变这个世界。当我渐渐成熟明智的时候,我发现这个世界是不可能改变的,于是我将眼光放得短浅了一些,那就只改变我的国家吧!但是我的国家似乎也是我无法改变的。当我到了迟暮之年,抱着最后一丝努力的希望,我决定只改变我的家庭、我亲近的人——但是,唉!他们根本不接受改变。现在在我临终之际,我才突然意识到:如果起初我只改变自己,接着我就可以依次改变我的家人,然后,在他们的激发和鼓励下,我也许就能改变我的国家。再接下来,谁又知道呢,也许我连整个世界都可以改变。 个人感悟 几年前在美股市场买了一点美股,当时看好英伟达,觉得英伟达是一家伟大的企业,本金很少,但是收益率很高。前段时间,买过蔚来,在2块买入,3块卖掉了。读完时间的玫瑰之后,作为自诩价值投资的人,感到深深的羞愧。自己还是有不少投机的思维,看好一家公司,长期持有他。投资可能也就是如此简单吧。

我有个小侄子了

9月2日,弟妹产下一子,从此我有了一个亲侄子-君酌,也成了“伯伯”辈的人了。 几个月前,弟弟说让我有空了也看看有了小孩起个什么名字,想着还早,也就随便看了看。结果,9月1日,弟弟发微信说,弟妹已经进产房了。我才想到名字还没想好。没有想象中的兴奋,也没有很激动,更多的是震惊。这才多久,我就已经成了伯伯辈,而家里也居然添了一名新丁。 周末跟奶奶发视频,她说,弟弟问他我和我哥的名字是谁起的,奶奶说是你爷爷起的,就想到这个名字就起了。(我这个名字起名的事情其实我是知道的),小时候,还总觉得自己的名字为啥这么简单,志向远大,不是很文艺。说到起名,那一瞬间,有点恍惚,就像是完成了一次交替,也有点遗憾。 奶奶说,生之前也不知道是男是女, 她还给想了几个名字,什么今年这疫情,起了个什么“战疫”之类的。。我说算了算了,哪能这么起,我都给想好几个了,他们选了君酌这个,我弟应该给你说了吧。他说嗯,好。没必要找算命的起。那个酌字给我发了拼音,我还没记住。 我妈辞掉了目前在做的一点工作,以后就专心带娃了。爸那边,估计年底也就不再做了,回县城,爸爸,妈妈和奶奶就在一起带娃,对他们的期望就是身体健康,别累着。生活开心。就好了。想起了那天看到的几句话,原话记不清楚了,大意就是父母这一辈,度过了国家比较苦的阶段,又在新阶段,接纳了掏空自己给儿女买房的观念,同时,又要承担所谓理所当然的帮带孩子的“义务”,最后,还有他们的父母需要他们来养。也许这就是命吧,我们能做的,大抵也就是尝试理解他们,体谅他们,尽自己所能的排解这种压力。 波波折折,弟弟和弟妹终于在外人看来是修成正果,未来的路还很长,还是要好好相处,家庭和睦,父母安好,加油。 对了,君酌,取自李白的“主人何为言少钱?径须沽取对君酌”,期望小侄子,人生洒脱,得意时须尽欢,失意时也能积极面对。

弟弟结婚了

2020年4月29日,弟弟弟妹结婚了。虽然有很多波折,但是总算有个大家都期待的结果。 以后还是希望弟弟承担起新家庭的责任,好好努力,把自己的家庭经营好。也希望本身成熟一些,做事情多考虑一点。 天那,难道我马上要有一个小侄子了。

一个没有问候的生日

爷爷奶奶 早上到公司的时候,Mac 的 日历突然弹出一个提醒 仿佛就在昨天,可再也没有机会问候了。时间已经过去了半年了。真的是太快了。 这半年来。奶奶还经常用爷爷的微信号和手机,浇水拼多多,在群里转发一些广告什么的。看到的的时候,就仿佛他还在一样,头像还是他和奶奶的一张合照,还是我当时拍的。 这半年,每周还是会给奶奶打电话,看她状态还不错,只是出去走的早。疫情原因,最近终于放开了。她也就出去逛逛。奶奶性格很好。女儿们离得近,多关心关心,生活也很开心。 前段时间,奶奶说手机号等她把什么都办好了。就不要续费了。最近还有一些东西没办完,说她不会交话费,让我交点续个费。那时候。也就假装没什么感受。一边聊着天,一边把话费交了。今天又悄悄续了一点费。 弟弟弟妹 17号的时候,经过一段时间的波折,弟弟领了结婚证,算是入了婚姻的坑。祝他们俩幸福生活,互相成长。周末的时候,两天都在陪着家里处理这些事情。弟弟工作后,经历了一点小挫折,本身性格也比较内向。在一些事情上想的不够多,也不够果断,比较容易纠结。 作为亲哥,在弟弟,弟妹,妈妈,亲人之间协调。最晚的时候,凌晨2,3点还在打电话,总算把这个事情搞定了。既往不咎,不计前嫌,希望他们俩真的幸福。双方也能更加珍惜彼此。 快结束的时候,妈妈突然跟我说发了个微信,说你做事真像你爷爷。也不知道是该高兴还是该伤心。以前家里有爷爷依靠,现在没有了,可是,终有一天,自己也成为了别人的一点依靠。 看到了一句话,“他去世后,我开始愿意相信这世界上有鬼。” 爸爸妈妈 妈妈最近为弟弟,弟妹的事情也操心的不行,总算尘埃落地。向前看,都会好的。爸爸随便干点事情,现在对爸爸妈妈的希望就是身体健康,其他什么都是次要的。 工作生活 某天称了一下体重,不可思议,居然过年后的这段时间,减轻了1公斤。但是感觉自己吃的挺好的。运动量也没变化,很是神奇。 周末在家倒是经常做饭。感觉自己手艺见长,以前想卖水果,现在看来做菜也行。最近工作很多,经常回家很晚。过段时间争取好点吧。 天气热了,出门戴口罩还是挺烦的。也希望疫情尽快过去。

几个浏览器的使用体验

前段时间,由于对 Chrome 即将成为 IE 和一些隐私方面的担忧。也顺便想尝试一下其他的浏览器,于是稍微换了一些。当然,现在又回到了 Chrome。简单记录一下。 Brave 浏览器,基于 Chromium 网页浏览器由 Mozilla 项目的联合创始人、JavaScript 的创造者布蘭登·艾克宣布。宣称阻止网站跟踪器和移除侵入式网络广告。确实可以拦截部分广告,另外有一个特色的挖矿钱包功能,就是你可以选择接受通知,看广告,然后获取虚拟货币。界面也很漂亮。但是这个东西。速度嘛,感觉也没有宣称的那么快。毕竟。道理上说不通啊。你都8倍了。Google 的开发者是水瓶不行么。。另外,这个玩意对于国内网站不够友好。国内的电商网站,比如淘宝,京东,等,基本上默认情况下,打开全屏幕空白。。因为认为是广告。 Firefox 浏览器,火狐浏览器,基本上算是最后一个有点名气的非 Chromium 内核的浏览器了。其实我觉得还不错,我比较喜欢内置的画中画功能。另外,速度上,我感觉也不差。但是Firefox 的 收藏夹功能真的是。。乱。最大的问题就是因为内核的原因。核心工作用的几个网站都用不了。因为开发网站的同学不兼容。不得不放弃。手机上也可以。 Edge 浏览器,微软基于 Chromium 的浏览器,界面风格我还挺喜欢,首页的广告默认存在,可以通过安装其他tab插件来解决屏蔽,支持 Chrome 扩展,但是注意,功能很不完善,很多同步功能都是废的。设置里面很多时间,你选了其他选项,根本看不到变化,刷新一下,发现好像生效了。有个特色的Collection功能。如果专门查个什么资料,还是有点用,但是可以通过新建一个收藏夹的文件夹来基本替代。手机版内置去广告插件,还不错。Mac 和 iOS 的一些联动基本没有,比如你想吧手机上的发给电脑,只能通过 Airdrop 了。不能直接发送。和 Chrome 不同。还需要完善,可以跟进。多等几个版本看看。 Safari 浏览器,其实挺简洁的,就是没啥进步,和公司不少网站也是不兼容的。插件也基本用不了,这点非常蛋疼,还要安装 App,阅读列表功能非常喜欢。可以同步。 除了 Safari,其他几个浏览器的手机上也是有阅读列表这个功能的,但是很奇怪,大家都不支持同步,只在手机上保存。估计觉得可以通过收藏夹替代。另外,不少浏览器对于手机和PC/Mac的收藏夹是默认分开的,叫做移动设备书签。这个真的是。有点难用。 除了 Edge 的手机 App 还是很好用的,其他的几个浏览器手机上的体验都很奇怪,比如最基本的 Tab 页新增。最好的还是 Safari。 综上所属,目前依然 Chrome。新时代的 IE。

Mysql中的B+树介绍

最近工作中遇到了一些索引的问题,发现自己其实并不了解,因此稍微了解下。在介绍B+树之前,需要先了解下B树,部分信息来源自参考文档。 什么是 B 树 B树概念 B树也称B-树,它是一棵多路平衡查找树(和二路对应)。二叉树我想大家都不陌生,其实,B树和后面讲到的B+树也是从最简单的二叉树变换而来,下面我们来看看B树的定义。我们定义m表示树的阶。阶数表示了一个节点最多有多少个子节点,那么一棵B需要满足以下几个条件 1.每个节点最多有m-1个关键key(可以存有的键值)。 2.根节点最少可以只有1个关键字。意思是也可以有多个。 3.非根节点至少有m/2个关键字。如果少了,那么就要进行树的调整 4.为了平衡查找,每个节点中的关键字都按照从小到大的顺序排列,每个关键字的左子树中的所有关键字都小于它,而右子树中的所有关键字都大于它。这个很简单了。没有这个保证的话,平衡查找无从谈起。 5.所有叶子节点都位于同一层,或者说根节点到每个叶子节点的长度都相同。 6.包括非叶节点在内,每个节点都存有key和数据,也就是对应的key和value。 也就是说,根节点的关键字数量k的范围:1 <= k <= m-1,非根节点的关键字数量范围:m/2 <= k <= m-1。 什么是B+树 B+树其实和B树是很相似的,特点是能够保持数据稳定有序,其插入与修改拥有较稳定的对数时间复杂度。B+ 树元素自底向上插入,这与二叉树恰好相反。 相同点 1.根节点至少一个元素 2.非根节点元素范围:m/2 <= k <= m-1 不同点 1.B+树有两种类型的节点:内部结点(也称索引结点)和叶子结点。内部节点就是非叶子节点,内部节点不存储数据,只存储索引,数据都存储在叶子节点。而B树都存储数据,这会导致查询性能不稳定,因为查找次数不确定。 2.内部结点中的key都按照从小到大的顺序排列,对于内部结点中的一个key,左树中的所有key都小于它,右子树中的key都大于等于它。叶子结点中的记录也按照key的大小排列。 3.每个叶子结点都存有相邻叶子结点的指针,叶子结点本身依关键字的大小自小而大顺序链接。 4.父节点存有右孩子的第一个元素的索引。 mysql中的选择 索引的数据结构 数据库中,数据都存在磁盘中,索引也多到大部分存在磁盘中,这样对于索引,每次查找数据时把磁盘IO次数控制在一个很小的数量级,最好是常数数量级。就这样,b+树应运而生。 MySQL 默认的存储引擎选择 B+ 树而不是哈希或者 B 树的原因: 1.哈希虽然能够提供 O(1) 的单数据行操作性能,但是对于范围查询和排序却无法很好地支持,最终导致全表扫描; 2.B 树能够在非叶节点中存储数据,但是这也导致在查询连续数据时可能会带来更多的随机 I/O,而 B+ 树的所有叶节点可以通过指针相互连接,能够减少顺序遍历时产生的额外随机 I/O; 如上图,是一颗b+树,关于b+树的定义可以参见B+树,这里只说一些重点,浅蓝色的块我们称之为一个磁盘块,可以看到每个磁盘块包含几个数据项(深蓝色所示)和指针(黄色所示),如磁盘块1包含数据项17和35,包含指针P1、P2、P3,P1表示小于17的磁盘块,P2表示在17和35之间的磁盘块,P3表示大于35的磁盘块。真实的数据存在于叶子节点即3、5、9、10、13、15、28、29、36、60、75、79、90、99。非叶子节点只不存储真实的数据,只存储指引搜索方向的数据项,如17、35并不真实存在于数据表中。 b+树的查找过程 如图所示,如果要查找数据项29,那么首先会把磁盘块1由磁盘加载到内存,此时发生一次IO,在内存中用二分查找确定29在17和35之间,锁定磁盘块1的P2指针,内存时间因为非常短(相比磁盘的IO)可以忽略不计,通过磁盘块1的P2指针的磁盘地址把磁盘块3由磁盘加载到内存,发生第二次IO,29在26和30之间,锁定磁盘块3的P2指针,通过指针加载磁盘块8到内存,发生第三次IO,同时内存中做二分查找找到29,结束查询,总计三次IO。真实的情况是,3层的b+树可以表示上百万的数据,如果上百万的数据查找只需要三次IO,性能提高将是巨大的,如果没有索引,每个数据项都要发生一次IO,那么总共需要百万次的IO,显然成本非常非常高。 b+树和索引的关系 联合索引,如果有一个3列索引(name,age,sex),则已经对(name)、(name,age)、(name,age,sex)上建立了索引; 1.我们知道IO次数取决于b+数的高度h,假设当前数据表的数据为N,每个磁盘块的数据项的数量是m,则有h=㏒(m+1)N,当数据量N一定的情况下,m越大,h越小;而m = 磁盘块的大小 / 数据项的大小,磁盘块的大小也就是一个数据页的大小,是固定的,如果数据项占的空间越小,数据项的数量越多,树的高度越低。这就是为什么每个数据项,即索引字段要尽量的小,比如int占4字节,要比bigint8字节少一半。这也是为什么b+树要求把真实的数据放到叶子节点而不是内层节点,一旦放到内层节点,磁盘块的数据项会大幅度下降,导致树增高。当数据项等于1时将会退化成线性表。 2.当b+树的数据项是复合的数据结构,比如(name,age,sex)的时候,b+数是按照从左到右的顺序来建立搜索树的,比如当(张三,20,F)这样的数据来检索的时候,b+树会优先比较name来确定下一步的所搜方向,如果name相同再依次比较age和sex,最后得到检索的数据;但当(20,F)这样的没有name的数据来的时候,b+树就不知道下一步该查哪个节点,因为建立搜索树的时候name就是第一个比较因子,必须要先根据name来搜索才能知道下一步去哪里查询。比如当(张三,F)这样的数据来检索时,b+树可以用name来指定搜索方向,但下一个字段age的缺失,所以只能把名字等于张三的数据都找到,然后再匹配性别是F的数据了, 这个是非常重要的性质,即索引的最左匹配特性。 参考 https://zh.wikipedia.org/wiki/B%2B%E6%A0%91 https://segmentfault.com/a/1190000020416577 https://tech.meituan.com/2014/06/30/mysql-index.html https://draveness.me/whys-the-design-mysql-b-plus-tree

2019 年终总结

2019 年很快过去了,以前有大把时间的时候没有感觉,而现在,时光如流水,怎么也抓不住。2019年,心情复杂。 失去的一年 这一年,爷爷生病离世,改变了很多事情。人生很短,一定要珍惜当下,珍惜眼前人。很多东西都可以通过各种方式重新获得。但是,生病,亲人,这些总是无能为力。今年体检,查出来中老年常见的血脂高。当然目前只高一点点,2019年,工作太忙。锻炼的很少。2020年,一定要坚持锻炼。 给父母也申请了体检,查下来没有什么大问题,心里放下很多,然后该买的保险,也给父母和自己都买了一些。虽然保额不算太高,但是也是有个保障。 对 XX 失去期待,基本上放弃了想要改变的想法,眼看着一些人被浪费,效率被无限拉低,还是多从自己做起,一屋不扫,何以扫天下。 得到的一年 2019年也是得到的一年,看了10多本书,心理学和经济学,还有一些小说,学习了一些新的技术, Golang,分布式事务,也成为 Seata 的 Committer,另外也对外做了一次500人场的Service Mesh 技术分享,之后又分享了几次。 这一年,在杭州买了房,定了居。买了Air Pods 2,买了 Surge Mac,拿到了公司5年陈的戒指,顺便买了一个手链,买了很多家居用品,自己处理家里的大大小小的事情,自己在家做饭,吃火锅。 这一年,也去湖北参加了同学的婚礼,在武大促膝长谈,跟朋友们在家里吃了饭,也去青海团建,吃了让人念念不忘的炕锅羊肉。 年末的时候,买了开言英语的年费会员,目前坚持了一个多月了。刚开始很简单,有了一点信心。2020年继续努力。 职业上有了晋升,当然也只是title变更,不过是资本家的把戏,不过5年,也算给自己一个交代。 寻求改变的一年 这一年,尝试体验了一些新的产品,比如彻底放弃了余额宝,转为银行的产品。比如开始熟练微信支付。 这一年,工作上,试图寻求突破,但很多事情并非能以人的意志为转移,并没有很好的达到自己的期望,作为公司层面可以理解,谁又能成为不可或缺的人。但是从个人角度来看。一旦没有上升空间,做的事情也没有比较大的价值,处在修修补补,到处支持,到处迁移的情况下,俗称搬砖,精力被无限的消耗,这样下去,核心竞争力没了,加班加不过新人,迟早成为马老板眼里的老白兔,这时候,就应该考虑是不是需要有新的机会和挑战,主动做出改变。2020年,多想一些,做点改变。 生活上,经历了一些改变,也迎接一些改变,变化总是存在的。如果一切可预知,那么人生岂不是也毫无意义。2020年,多锻炼身体,一周两次不能少,也出去走走。 2020 年 2020年,多做一些高价值的事情,能够坚持读一些英文的paper,探索一些新的非工作上的领域,最重要的,坚持读书不能少。

理解 CAP 理论

背景 CAP理论 实际上听起来非常简单,但是有时候,遇到一些具体的问题的时候, 还是不能很清晰的分辨出来,到底是CP还是AP,以及一些其他的问题。因此,专门作为"生产者"来学习下,加深理解。 首先,在理论计算机科学中,CAP定理(CAP theorem),又被称作布鲁尔定理(Brewer's theorem),它指出对于一个分布式计算系统来说,不可能同时满足以下三点: 1.一致性(Consistency) (等同于所有节点访问同一份最新的数据副本) 2.可用性(Availability)(每次请求都能获取到非错的响应——但是不保证获取的数据为最新数据) 3.分区容错性(Partition tolerance)(以实际效果而言,分区相当于对通信的时限要求。系统如果不能在时限内达成数据一致性,就意味着发生了分区的情况,必须就当前操作在C和A之间做出选择。) 根据定理,分布式系统只能满足三项中的两项而不可能满足全部三项。 这个定理起源于加州大学柏克莱分校(University of California, Berkeley)的计算机科学家埃里克·布鲁尔在2000年的分布式计算原理研讨会(PODC)上提出的一个猜想。 在2002年,麻省理工学院(MIT)的赛斯·吉尔伯特和南希·林奇发表了布鲁尔猜想的证明,使之成为一个定理。 举例 假设你明天就要放长假了,你想买一本战争与和平的书籍,你最喜欢的在线商城里面只有一本了。 一致性: Consistency,在Gilbert and Lynch 的论文里,他们也用 “Atomic” 原子性来代替一致性这个单词。 在买书的这个例子里,你要么就是把书放到了购物车,要么就是放失败了,要么付款,要么没付款,不可能说放了一半,或者说买了一半。只有一本书,如果两个客户都准备买,缺乏一致性的话,如果两个人都完成了下单,可能会出问题。比如两个人都下了单,当然,在这个例子中,并不严重。 我们也可以用数据库来解决这个问题,数据库里有个字段减去个1,然后当及其他客户也要付款的时候,我们提示他没了。 数据库看很好用。因为具有ACID的能力。既有一致性,又有原子性,中间状态对第二个客户端是不可见的。是隔离的。因为第二个客户端再下单的时候,另一个用户在事务中的话,就锁住了数据库那条记录。 可用性: 可用性就是说,当你需要的时候,大部分情况下,服务都是可以为你服务的。以买书为例,在用户A开启事务的时候,有那么几毫秒是锁表的,这个阶段,服务可以认为对其他用户是不可用的。并不是说要时时刻刻可用,一般会有个可用率的指标。如果记不住,可以通过这里来计算: https://uptime.is/99.99999 分区容错: 如果你就一个数据库,一个服务端,那一般也都是原子的,如果挂了,服务不可用,但是数据还是一致的。 一旦你把数据和代码逻辑,开始部署在不同的节点上,这时候就存在分区。如Node A 不能和Node B通信来,这种分区问题经常出现。 用图来证明: 在一个网络环境下,有两个节点,N1和N2,共享相同的数据V,在买书这个例子中,这个数据里面存储的就是有多少本书,假设初始值是V0,在N1上运行一个买卖算法,A,假设这个算法没有bug,非常正确,可心来,N2也是类似的,叫做B,A写了一个新值到V中,然后B从V中读取。 正常流程是这样,A写完之后,N1和N2通过一个消息(非具体的消息),将这个值同步给N2。然后B也就能读到了。 1.A写了一个值V1 2.从N1发了个消息M到N2。 3.B也能从V中读到V1了 但是,现实没有这么美好 网络发生了分区,从N1到N2的消息没有投递成功。这样,到第三步的时候,N2读到了V0这个错误的值。 如果M是一个异步消息,那么N1都没办法知道N2是不是收到了。即使有办法保证M这个消息一定发出去了。那么N1也没办法知道,这个消息是不是被投递了,也不知道N2处理的时候,有没有问题。那么,如果我们把M改成同步消息呢。也不行,因为这意味着将A写值到N1,和从N1到N2更新事件是一个原子操作。 CAP告诉我们,如果我们想要A和B高度可用(低延迟),我们就要N1和N2保持分区容错,比如出现消息丢失,消息未投递,硬件故障,或者处理失败。这种情况下,就会出现有时候一些节点任务V是V0,另一些节点认为是V1. 如果有一个事务,叫做a1,a1可能是一个写操作,a2是一个读操作,在本地系统中,通过数据库或者自己加锁,加隔离是很简单的。可以强制a1写完之后,a2才发生,但是在分布式环境中,一旦加了这些东西,就影响额分区容错和可用性。 处理CAP CA 不要 P,不要分区容错 不保证分区容错,那么你可以部署在一个台机器上,但是容量受限。并且还是会存在网络问题。分布式环境下,网络分区是必然的。除非你就不想做分布式。 在分布式的环境下,网络无法做到100%可靠,有可能出现故障,因此分区是一个必须的选项,如果选择了CA而放弃了P,若发生分区现象,为了保证C,系统需要禁止写入,此时就与A发生冲突,如果是为了保证A,则会出现正常的分区可以写入数据,有故障的分区不能写入数据,则与C就冲突了。因此分布式系统理论上不可能选择CA架构,而必须选择CP或AP架构。 从Google的经验中可以得到的结论是,无法通过降低CA来提升P。要想提升系统的分区容错性,需要通过提升基础设施的稳定性来保障。 所以,对于一个分布式系统来说。P是一个基本要求,CAP三者中,只能在CA两者之间做权衡,并且要想尽办法提升P。 CP 不要 A 不要可用性 当你想要分区容错的时候,并且可以容忍长时间的停机或者无影响。就可以舍弃可用性。 一个保证了CP而一个舍弃了A的分布式系统,一旦发生网络故障或者消息丢失等情况,就要牺牲用户的体验,等待所有数据全部一致了之后再让用户访问系统。 设计成CP的系统其实也不少,其中最典型的就是很多分布式数据库,他们都是设计成CP的。在发生极端情况时,优先保证数据的强一致性,代价就是舍弃系统的可用性。如Redis、HBase等, 常用的Zookeeper也是在CAP三者之中选择优先保证CP的。ZooKeeper是个CP 的,即任何时刻对ZooKeeper的访问请求能得到一致的数据结果,同时系统对网络分区具备容错性。但是它不能保证每次服务请求的可用性,也就是在极端环境下,ZooKeeper可能会丢弃一些请求,消费者程序需要重新请求才能获得结果。 ZooKeeper 是分布式协调服务,它的职责是保证数据在其管辖下的所有服务之间保持同步、一致。所以就不难理解为什么 ZooKeeper 被设计成CP而不是AP特性的了。从实际情况来分析,在使用 Zookeeper 获取服务列表时,如果 ZooKeeper 正在选举或者 ZooKeeper 集群中半数以上的机器不可用,那么将无法获取数据。所以说,ZooKeeper 不能保证服务可用性。 Eureka 则是一个AP系统,一部分节点挂掉不会影响到正常节点的工作,不会出现类似 ZK 的选举 Leader 的过程,客户端发现向某个节点注册或连接失败,会自动切换到其他的节点。 只要有一台 Eureka 存在,就可以保证整个服务处在可用状态,只不过有可能这个服务上的信息并不是最新的信息。 SofaRegistry 也是一个AP系统。 AP 不要 C 不要一致性 要高可用并允许分区,则需放弃一致性。一旦网络问题发生,节点之间可能会失去联系。为了保证高可用,需要在用户访问时可以马上得到返回,则每个节点只能用本地数据提供服务,而这样会导致全局数据的不一致性。 这种舍弃强一致性而保证系统的分区容错性和可用性的场景和案例非常多。前面我们介绍可用性的时候说到过,很多系统在可用性方面会做很多事情来保证系统的全年可用性可以达到N个9,所以,对于很多业务系统来说,比如淘宝的购物,12306的买票。都是在可用性和一致性之间舍弃了一致性而选择可用性。 举个例子,你在12306买票的时候肯定遇到过这种场景,你购买的时候提示你是有票的(但是可能实际已经没票了),你也正常下单了。但是过了一会系统提示你下单失败,余票不足。这其实就是先在可用性方面保证系统可以正常的服务,然后在数据的一致性方面做了些牺牲,会影响一些用户体验,但是也不至于造成用户流程的严重阻塞。 但是,我们说很多网站牺牲了一致性,选择了可用性,这其实也不准确的。就比如上面的买票的例子,其实舍弃的只是强一致性。退而求其次保证了最终一致性。也就是说,虽然下单的瞬间,关于车票的库存可能存在数据不一致的情况,但是过了一段时间,还是要保证最终一致性的。也就是说,最终不会出现,2个人买到了同样的票。 对于多数大型互联网应用的场景,主机众多、部署分散,而且现在的集群规模越来越大,所以节点故障、网络故障是常态,而且要保证服务可用性达到N个9,即保证P和A,舍弃C(退而求其次保证最终一致性)。虽然某些地方会影响客户体验,但没达到造成用户流程的严重程度。 怎么选择呢 既要又要。那怎么办? 虽然三个不能保证,但我们能不能在一致性上作出一些妥协,不追求时时刻刻的强一致性,转而追求最终一致性,所以引入 BASE 理论。 在分布式事务中,BASE 最重要是为 CAP 提出了最终一致性的解决方案,BASE 强调牺牲高一致性,从而获取可用性,数据允许在一段时间内不一致,只要保证最终一致性就可以了,实现最终一致性。 弱一致性:系统不能保证后续访问返回更新的值。需要在一些条件满足之后,更新的值才能返回。从更新操作开始,到系统保证任何观察者总是看到更新的值的这期间被称为不一致窗口。 最终一致性:这是弱一致性的特殊形式;存储系统保证如果没有对某个对象的新更新操作,最终所有的访问将返回这个对象的最后更新的值。 BASE 模型 BASE 模型是传统 ACID 模型的反面,不同于 ACID,BASE 强调牺牲高一致性,从而获得可用性,数据允许在一段时间内的不一致,只要保证最终一致就可以了。 BASE 模型反 ACID 模型,完全不同 ACID 模型,牺牲高一致性,获得可用性或可靠性:Basically Available 基本可用。 支持分区失败(e.g. sharding碎片划分数据库)Soft state 软状态,状态可以有一段时间不同步,异步。 Eventually consistent 最终一致,最终数据是一致的就可以了,而不是时时一致。 参考 http://www.julianbrowne.com/article/brewers-cap-theorem https://www.cnblogs.com/13yan/p/9243669.html

深入理解Raft协议

本文部分以JRaft为例,来详细介绍Raft。 Raft 来源 首先,我们介绍 Raft 问题的来源,Raft 实际上是一个一致性算法的一种实现,和Paxos等价,但是在实现上,简化了一些,并且更加易用。 这里面又引入了两个名字。一个是一致性,一个是Paxos,我们先说一致性, 一致性是一个可容错的分布式系统重的最基本的一个问题,一致性包含了“多个服务器对同一个值达成共识,一旦对某个值达成共识,这个决定就是不可变了”,通常,一致性算法,当多数服务器可用的时候,才有效,比如5个server,那么2个挂了,是没问题的,但是再挂一个,超过一半,就不能提供服务了。这句话也说明,他不会返回错误的值,因为都不提供服务了。 一致性通常和 Replicated State Machines(后面简称RSM)相关,最早提出是在图灵奖得主Leslie Lamport的著名论文"Time, clocks, and the ordering of events in a distributed system(1978)“论文中,比较系统性的阐述是在Fred Schneider的论文” Implementing fault-tolerant services using the state machine approach(1990)“中。 它的基本思想是一个分布式的RSM系统由很多个replica组成,每个replica是一个状态机,它的状态保存在一组状态变量中。状态机的状态通过并且只能通过外部命令(commands)来改变。比如你可以把MySQL服务器想像成一个状态机。它每接收到一条带修改功能的SQL语句(比如update/insert)就会改变它的状态。一组配置好replication的MySQL servers就是典型的RSM。 RSM能够工作基于这样的假设: 如果一些状态机具有相同的初始状态,并且他们接收到的命令也相同,处理这些命令的顺序也相同,那么它们处理完这些命令后的状态也应该相同。 因为replica都具有相同的状态,所以坏掉任何一个也没有关系。有了RSM之后理论上可以做到永远不会因为机器的物理故障而丢失数据。 也就是说,根据论文的指导,比较普遍的构建容错系统的方法是,每个服务器都维持一个状态机和一个Log,状态机就是我们想要实现容错的一个组件实现,比如想实现一个分布式环境下可容错的 Hash Table, 客户端会和这个状态机交互,每个状态机从log中获取input命令,在这个Hash Table 的例子中,这个log 可能是类似 把X 设置成3这样的命令,一致性算法必须确保,如果任何一个状态机在第N个命令中认可了n被设置为了3,那么其他机器上的状态机器就绝对不应该设置为其他值,这就能保证其他所有的机器总是处理相同的命令序列,最终大家都是同样的状态。 至于Paxos,这里可以先简单理解就是个一致性算法的实现方式,和 Raft 类似。 总结就一致性是为了解决分布式环境下的容错问题,而Raft 和 Paxos 是其中的一种实现。 核心怎么实现呢 要实现Raft,根据作者的表述,通过对状态空间的简化,以及问题的分解,实现方只需要实现的就是各个子问题 状态空间: 状态太多就会增加理解的困难程度。Raft 算法尽可能地确定各个环节的状态。典型地,Raft 算法采用 strong leader 的模型,每个日志的读写均由 Leader 从中主动协调,这样一来,整体系统的数据流将非常简单:从 Leader 流行 Follower。而且每个节点的状态也只有 3 种:Leader,Candidate 和 Follower。 子问题: Leader election:描述如何从集群的几个节点中选举出 Leader; Log Replication:描述如何将日志同步到各个节点从而达成一致; Safety:定义了一组约束条件来保证 Raft 算法的强一致性; Membership changes:描述如何变更集群关系(增加或者减少节点); Leader election Raft的节点被称为peer,节点的状态是Raft算法的关键属性,在任何时候,Raft节点可能处于以下三种状态: Leader:Leader负责处理客户端的请求,同时还需要协调日志的复制。在任意时刻,最多允许存在1个Leader,其他节点都是Follower。注意,集群在选举期间可能短暂处于存在0个Leader的场景。 Follower:Follower是被动的,它们不主动提出请求,只是响应Leader和Candidate的请求。注意,节点之间的通信是通过RPC进行的。 Candidate:Candidate是节点从Follower转变为Leader的过渡状态。因为Follower是一个完全被动的状态,所以当需要重新选举时,Follower需要将自己提升为Candidate,然后发起选举。 但是这种机制也带来一个麻烦,如果一个节点 因为自己的原因没有看到 Leader 发出的通知,他就会自以为是的试图竞选成为新的Leader,虽然不断发起选举且一直未能当选(因为Leader和其他船都正常通信),但是它却通过自己的投票请求实际抬升了全局的 Term 为了阻止这种“捣乱”,可以设计一个预投票 (pre-vote) 环节。候选者在发起投票之前,先发起预投票,如果没有得到半数以上节点的反馈,则候选者就会放弃参选,也就不会提升全局的 Term。 Candidate 被 ET(Election Timeout) 触发 Candidate 开始尝试发起 pre-vote 预投票 Follower 判断是否认可该 pre-vote request Candidate 根据 pre-vote response 来决定是否发起 RequestVoteRequest Follower 判断是否认可该 RequestVoteRequest Candidate 根据 Response 来判断自己是否当选 线性一致性 线性一致读是在分布式系统中实现 Java volatile 语义,当客户端向集群发起写操作的请求并且获得成功响应之后,该写操作的结果要对所有后来的读请求可见。其实就是CAP里面的C, Raft log read 实际上如果基于Raft本身的设计,因为每次 Read 都需要走 Raft 流程,Raft Log 存储、复制带来刷盘开销、存储开销、网络开销,走 Raft Log不仅仅有日志落盘的开销,还有日志复制的网络开销,另外还有一堆的 Raft “读日志” 造成的磁盘占用开销,导致 Read 操作性能是非常低效的,所以在读操作很多的场景下对性能影响很大,在读比重很大的系统中是无法被接受的,通常都不会使用。

《非暴力沟通》笔记

最近读完了《非暴力沟通》这本书,看完之后,整体感觉还好,感觉核心就下面这四点 1.清楚地表达观察结果 区分感受和观察,表达的时候,一定要表达清楚,不要只表达感受,即使你批评一个人,也要说清楚,你看到了什么事情,让你觉得你应该批评他,而不是一开口就是你不对,你错了。 要不带评论的冷静观察。 2.表达感受 在表达完你的观察之后,要表达感受,这个主要是为了自己,让你能观察到自己的感受,让你知道什么时候,你是什么感受,是否是正向的。如何处理,注意,“我觉得”,“我想”,这个词带有评判色彩,当你说这个的时候,请重新组织语言。 3.说出哪些需要导致那样的感受 说出,哪个行为,或者哪个操作让你感受这样。比如是不是冒犯了你这样。 4.具体的请求 最后,提出具体的请求,你希望对方怎么做,才能让你好受,达到你的期望。请求的时候要具体,不能是抽象的。比如,你做的更好一点,这种对方无法决策怎么做,应该尽量具体,也避免双方理解有误。 这里注意要区分请求和命令,如果你说出的请求,别人拒绝会要承担后果,那多半是命令,而不是请求。