弟弟结婚了

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.具体的请求 最后,提出具体的请求,你希望对方怎么做,才能让你好受,达到你的期望。请求的时候要具体,不能是抽象的。比如,你做的更好一点,这种对方无法决策怎么做,应该尽量具体,也避免双方理解有误。 这里注意要区分请求和命令,如果你说出的请求,别人拒绝会要承担后果,那多半是命令,而不是请求。

Wedding of Friends

十一参加了两位大学好友的婚礼,昨天晚上回到了杭州。感触颇深,写点东西记录一下。 参加完婚礼之后,回到武汉,大家聚完餐,听到峰少和晓洁给大家准备了5周年的蛋糕,也刚好快是他们结婚2周年,很是惊喜。在吃饭的时候,玩了几个游戏,每个人基本上都说了一些,比如自己男朋友的10个优点,自己女朋友做的最让自己印象深刻的几件事情。等等。单身的几位说了一下感想,或者是说了一下曾经的经历。这个时候,看到了大家不同的一面。总之,幸福的人各有各的幸福,不幸的各有各的不幸。哈哈哈。 晚上回到酒店,已经很晚了。来到了武大奥体,席地而坐,点起了蜡烛。 然后讲起了一些5年的感触,包括结婚后的感受,在生活中的感受,如何做得更好,哪些做得不好的。对感情的看法。对工作的看法。以及八卦了一下过去。奥体的风吹着,有人说了一句想回到过去,却被其他人道了一声醒醒。哈哈。 祝婚姻幸福美满,爱情生活顺利,要向前看,更不惧将来。

Principle Note

最近在读一本书,《原则》,有一些感触比较深的点,分享下。这本书前半部分介绍作者在桥水的工作历程,建议直接忽略。从第二部分看起来即可。 1. 独立思考 (1)你想要什么; (2)事实是什么; (3)面对事实,你如何实现自己的愿望 知道自己想要什么,知道现实是什么,然后找办法实现,可以求助别人,如果还是实现不了,建议认清楚这种鸿沟。 2. 以可信度加权的方式做决定 作者认为一个人除了自信以外,要认识到自己的弱点,做决定的时候要配合更加可信的人,以可信度加权的方式做决定。比如你去看医生,医生说你并很重,建议你住院,而你觉得自己身体并无碍,这时候你会怎么做,你当然是更相信医生才对,因为医生在这一领域更专业,如果你自己在医学上的可信度为1,那么医生就是90,所以。 也就是说要经常好奇为什么其他聪明的人对事情的认识与我不同,来促使自己既从自己的视角看问题,也从别人的视角看问题。以看到很多维度,如果只从自己的视角看问题,是看不到这么多的。要懂得了如何对不同人的观点进行加权,从而选择最好的观点, 那如何定义“可信”,作者认为这样的人有两个特征:曾反复地在相关领域成功找到答案(至少成功过三次,拥有过硬履历);在被问责的情况下能对自己的观点做出很好的解释。” 这个点说的非常好,告诉我们什么时候,如果做正确的决定。如果你评估对方在这方面是这个新手,那多数情况下你更应该相信自己。 3. 做到头脑极度开放 影响合理决策的两个最大的障碍是你的自我意识和思维盲点。这两个障碍让你难以客观地看到你和你所处环境的真相,难以通过最大限度地利用他人的帮助来做出最佳决策。 自我意识指的是,要有效行事,你就绝不能允许“想要自己正确”的需求压倒“找出真相”的需求。让心里那个想要维护自己所谓尊严和正确的小人退下去,而且要保持谦逊和心胸开阔,以便你能动用自己的最佳思维,而如果你对自己掌握的知识和擅长的事情过于自豪,你学到的东西就会变少,决策质量就会变低,也将难以充分发挥自己的潜力 思维盲点指的则是,一个人的能力有限,不要过于自信,起码评估在哪些方面自己比较好,但是在自己的短板上,依靠擅长者的帮助。 作者还举了个例子,一个有高度创造性和目标导向性的人擅长设想新主意,但可能会低估日常生活细节的价值,而后者也很重要。他也许过度投入地追求长期目标,因而鄙视那些关注日常生活细节的人。类似地,一个任务导向的人善于处理细节,但可能会低估创造性的价值,甚至可能会为了效率而压制创造性。这两个人也许能组成一个好团队,但也有可能难以充分利用各自的优势,因为不同的思维方式让他们难以看到对方思维的价值。” 在日常工作中,这两个人最好能先把自己的本职做好,比如leader,要有大局观,但是不能空想。要有合理的把控,员工如果在信息掌握不足的情况下,首先做好细节上的事情,也要积极了解做这样的意义和在全局的用处。 4. 合理选择 这里面,我觉得久一点,最好的选择是好处多于坏处的选择,不是毫无坏处的选择。看看有些人,发现一点问题就反对某件事,而不合理权衡所有的优缺点。这样的人通常不善于决策。 这个告诉我们,没有银弹,一旦有人提出一个能解决一切问题的方案,请警惕。推广到工作和生活中,就是没有完美的答案,一定会有一些妥协,但可以选择好处远远大于坏处的,并评估坏处是否可以接受。 5. 团队合作 主持开会,要支持开会目的,开会对象,切忌胡乱跑题,绝不展开无关话题,保持高效,要允许反对意见,并充分讨论,而不是主管给结论,然后提出反对意见,并不理会,正确的应该是,会上充分讨论,会下严格执行,一旦决策,就不应该再有不同意见。否则决策多半是失败的。要么实行不下去。要么是其他的。 6. 不要担心个人形象 不要为自身形象担心,只需关心能不能实现你的目标。也就是说不要有所谓的偶像包袱,觉得自己应该什么都自己搞定,要比别人更厉害。遇到别人更了解的,积极求援,目标是把任务完成,而不要纠结于个人形象。 同时你不擅长的领域请教擅长的其他人,这也是一个你无论如何都应该培养的出色技能,这将帮助你建立起安全护栏,避免自己做错事。 找到、接受,并学会如何应对你的弱点,则可以更好的进步。 7. 失败则反思 虽然很不喜欢如何成功类似的文章,但是作者这句话说的还是比较在理的:成功的关键在于,既知道如何努力追求很多东西,也知道如何正确地失败。“正确地失败”是指,能够在经历痛苦的失败的过程中吸取重要的教训 不管是个人的失败,还是某些项目或者工作目标上的失败,一定要反思。而不能让部分的成功掩盖。 另外,不要把成功的装饰误认为成功本身。有追求成就的方向感是很重要的。有的人痴迷于一双1200元的鞋或一辆时髦的汽车,这样的人很少会感到快乐,因为他们不知道自己真正想要的是什么,因而也不知道什么能满足他们 这些都只是成功的装饰,并非成功本身。。 8. 汇总 作者在书中说了很多,我个人印象比较深刻的就是这么几点。总结下来,也提醒自己多多注意,能够有所提高。