从苹果发布会看华为的创新地位

北京时间2019年9月11日凌晨1点,苹果秋季发布会在乔布斯大剧院如期举行,发布了最新款手机 iphone11系列。 iphone11系列能拿得出手提升主要有两个: 一是后置1200万三摄,兼顾广角和长焦,4倍光学变焦,增强夜间模式。二是最新7nm仿生芯片A13,集成85亿个晶体管,提升AI计算能力。注意不支持5G! 此外媒体还总结了6大卖点,除上面两点还包括:电池更大,18W快充,全新配色,售价更便宜。 通过苹果的发布会,我们可以看到目前全球手机厂商的创新点主要聚焦在三个方面:拍照、芯片、AI计算。 而横向比较,我们看一下华为。 首先华为是手机多摄像头方案的鼻祖,华为每款最新旗舰机手机发布拍照能力都会霸榜DxOMark。最新mate30在拍照能力上让人充满期待。 从16nm的950,到7nm的990,华为已经站在了CPU制程的最前沿。麒麟990芯片是世界上首款支持5G双模的7nm终端芯片,集成首次超100亿晶体管。将会用在随后发布的Mate30系列上。这次苹果发布会第一次吧麒麟芯片作为对比对象。但是却拿的华为上一代产品麒麟980. AI方面华为是最先提出NPU的概念,到990已经是好几代了。 我们发现不知不觉华为已经站在了手机创新的前列甚至于制高点上。苹果已经不在是创新的代名词。有人评论这可能是苹果最后一次享受乔布斯的遗产红利,通过简单修改一下参数就可以卖的很好。 最后让我们拭目以待华为9.19 最新Mate30系列全球发布会。

2019年9月12日 · 1 分钟

大岩评“小米自研30W无线闪充”

小米9月9日发布了全球首款30W无线闪充,然后小米高管微博开始宣传造势。 然而有网友质疑小米30W无线闪充使用了和华为相同的供应商IDT的技术方案。 时隔三日,9月12日小米产品总监王腾Thomas长篇回应质疑。 大肆宣传快充最开始有OV发起的,“充电五分钟通话两小时” 广告狂轰乱炸确实带起了OV销量。 前段时间荣耀发布荣耀9X用了10W充电,小米高管卢伟冰带了一波节奏,我想小米可能想趁热继续在充电上冲一冲,给粉丝一个小米有技术的印象。 但是我们分析这篇王腾的回复博文,看到的不是小米对技术的自信,而是心虚和掩饰。看到这5条创新技术,我感受到是小米的绞尽脑汁,勉强无力。 且看其中包括充电策略,保护算法这不是一个手机充电必须有的吗? 安全加密机制算法,我都有点乱了,这里是说加密算法,还是加密的机制?有这样称呼的吗?这个自研的算法安全吗? 可以想象小米是费了多大的劲才挑选出这样的让读者感觉表面有点技术含量的词语啊。 然而最最核心的无线充电芯片,也被加上了“供应商根据小米的需求和电路架构为小米设计”的修饰语。 我的结论是: 雷军一直说自己是科技节的无印良品,追求颜值和性价比。但是手机是一个高科技产业,手机厂商竞争进入了白日化阶段,没有核心技术的厂商会逐渐被淘汰和边缘化。 小米的底牌可能真的不多了。俗话说穷则思变,小米是时候需要把更多精力放在科技创新,打造更多核心竞争力上,而不是高管集体在微博上面耍嘴皮子。

2019年9月12日 · 1 分钟

大岩评“卢十瓦”事件

2019年7月23日,荣耀在西安发布了荣耀X系列的下一代产品荣耀9X系列。4800像素三射,升降摄像头,PC液冷,4000mA大电池,前置指纹识别。同时搭载7nm制程的麒麟810芯片,拥有方舟编译器、EROFS超级文件系统、GPU Turbo 3.0、麒麟Gaming+技术、AI视频防抖,AI智慧通信2.0等多项华为自研高科技。 然而它有一项不尽人意的地方,就是充电仅支持5V2A=10W功率充电器。 小米副总裁卢伟冰抓住这一点不放,在微博上连续多天发文提及此事: 7月23日:“今天友商的产品让人费解,请教: 1.手机支持18W快充,inbox充电器不支持2.手机和充电器都不支持,是哪个?请大家指教” 7月24日:“今天的手机竞争,产品一定要有自己的特色和长板,而且一定不能有短板,尤其是用户非常关注的处理器、拍照、电池、快充、外观材质等,绝对不能偷工减料。卖2399元的手机只支持10W充电,在Redmi团队的话产品经理肯定被开!” 7月25日:“炮制虽繁,必不敢省人工,品味虽贵,必不敢减物力 ”7月26日: “按照友商的理论,我不用做任何测试,先下个结论:充电能力,10W的友商9X/9XPro,一定远落后于18W的小金刚Pro。因为这个世界真的是有“科学常识”存在。世界最顶级的专家,也不可能把10W优化出18W的快充能力。” 7月27日:“五年前的红米Note第一代,就已经是10W充电了…所以最近有点恍惚,好像回到了几年前。但,永远相信美好的事情即将发生” 7月28日:“Redmi 7A是我们高品质的入门款手机,4000mah大电池,售价只要549元,同样标配10W充电。我在想,下一代还要不要继续用10W呢?” 为了把事情彻底闹大 7月29日: “Redmi全民快充计划,划重点: 1.价值29.9元的18W充电器小米商城1元闪购 2.Note7 6+64版本闪降200元仅1199并加送18W充电器。 明天上午10.08分开售,全民进入18W快充时代,告别10W!” 于是网友送了一个外号 叫 “卢十瓦”, 并且产生一个功率单位1卢=10W 卢伟冰在最新的微博里也自嘲“最近不少网友叫我“卢十瓦”,我觉得这其实是件好事,因为这一定会促进产业的共同进步,能给用户带来更好的体验,我预测友商的下一代产品也不会再用10W充电了。想做出好产品就一定要较真!”, 以行业良心自居,和网友打的是热火朝天。这就是“卢十瓦”事件的背景。 我想从另外一个角度分析这个问题:荣耀9X用10W就是偷工减料吗? 荣耀没有技术水平让荣耀9X用上更大功率的快充吗? 显然不是,我想打个比喻:有一天马云骑着自行车锻炼身体,一位开着马自达的上班族看到了,嘲笑马云没有开上马自达。 马云是开不起马自达吗? 但是此时此刻马云他就是需要骑自行车。 荣耀千元机直接上7nm对小米来说就是致命性的降维打击。10W充电就是故意卖个破绽给你。小米体会不到自己的危机,反而操弄起自己熟悉的社会营销。 试想小米任何一款手机,其它任何手机厂商是不是立马就可以造出来? 华为的手机,小米可以造出来吗? 甚至于OV厂手机的一两个特性,小米都搞不出来。没有核心关键技术的企业是不可持续的,也许这就是为什么在资本市场,小米盈利能力不错,仍然被看衰,股票一跌再跌的原因吧。 通过荣耀9X,“卢十瓦”事件,表面看到的是小米的接地气,性价比。更深层次看到的是小米的未来危机,没有核心关键技术,深陷社会营销的小米到底还能走多远?

2019年8月28日 · 1 分钟

Junit单元测试碰到静态变量如何处理

写单元测试用例,是程序员的好习惯,写java程序,一般使用Junit写单元测试。 我在写单元测试用例到时候,遇到一个问题:Junit在整个project中是一个java进程,如果你的程序里涉及静态变量,就会导致两个单元测试类之间相互影响。 你可以每次beforeClass初始化静态变量,但是有时候依赖了很多开源软件,你都不知道究竟一个测试流程里用到了哪些静态变量,甚至不知道如何还原它们。 最有效直接的办法就是每个测试用例都使用一个独立的classloader,也就是说每个test case都是类隔离的。 参考https://stackoverflow.com/questions/42102/using-different-classloaders-for-different-junit-tests 这篇帖子里的回复。实现了这个功能。 具体源码: https://github.com/johnyannj/junit-alone 用法如下: maven引入依赖 <dependency> <groupId>com.zhaoyanblog</groupId> <artifactId>junit-alone</artifactId> <version>1.0.1-SNAPSHOT</version> </dependency> 在你的测试用例中,用AloneRunner代替你原来真实的Runner,并把你真实的Runner,设置给@AloneWith @RunWith(AloneRunner.class) @AloneWith(JUnit4.class) public class JunitAloneTest { @Test public void test() { StaticClass.staticNum++; Assert.assertEquals(1, StaticClass.staticNum); } } 这样你的测试用例就会使用一个独立的classloader来执行了, 试试看吧。

2019年4月28日 · 1 分钟

从大嘴Mate20发布会后采访看雷军三大败笔

10月26日,在mate 20系列发布会之后,余承东接受媒体采访,有人问到mate 20系列的Dxomark评分,大嘴回复“因为P20Pro已经拿下了第一,华为不愿意看到榜单上都是华为手机,想给友商留位置。”在这里我想到了雷军,我认为雷军在类似事情上有三大败笔。 第一: 收购安兔兔 小米创业之初的口号是“为发烧而生”,主打的是性价比,怎么体现手机的性能呢?那就是跑分,有段时间雷军是把“不服跑个分”挂在嘴上的。安兔兔是跑分软件中比较出名的一个,小米也一直占据安兔兔榜首的位置,本来是个米粉们骄傲的事情。然而雷军把它收购了(눈_눈),彻底毁掉了安兔兔的江湖地位,没有人在看重评分,这也毁掉了小米一个炫耀的资本。老罗曾在和王自如的辩论中透露: 有人曾经撺掇他收购另外一个评分软件鲁大师,老罗没答应。看来老罗在某些方面还是比雷军有原则啊。 第二: 投资王自如 国内手机评测做的比较有规模的,王自如的zealer是一个,一部手机有哪些优点和缺点,这些评测视频里的观点很重要,会引导部分消费者的购买选择。老罗也看重了这一点,手机还没发布,就花钱让王自如做评测,提意见。王自如后面不地道的做法就不说了。老罗在辩论里透露了一个信息“小米投资了王自如”。王自如的zealer的独立第三方的身份遭到质疑,这几年都没翻过身来,只能低调做视频。 第三: 合伙潘九堂 手机好不好,还有一个宣传是渠道就是大v推荐,有时候一款手机发布前,手机厂商都会送一些手机给这些大v明星试用,大v们发个点评的微博,也能给手机带来很多人气。潘九堂就是一位,挂名“华强北电子行业研究所分析师”类似职位,活跃于微博,发表一些“独到”见解。他要推荐个手机,还是有人认的。然后就在某一天,潘九堂摇身一变,变成了“小米产业投资部合伙人”,专门给小米赚起了吆喝。 雷军的这些行为就像评委是选手的一大妈,监工是包工头的二姨夫,做的太明显,也太蠢,败笔~

2018年11月13日 · 1 分钟

基于SCRAM-SHA256实现的Cassandra安全认证插件

Cassandra提供认证机制,保证访问安全,但是默认的PasswordAuthenticator是简单的用户名密码认证,客户端在连接后传输用户名密码,服务器确认有效即认证通过。但是在认证的过程中直接传输的是明文密码,有被抓包泄漏的风险。 Cassandra服务端和JAVA客户端本身都支持SASL扩展 https://tools.ietf.org/html/rfc4422 SCRAM-SHA256是SASL的一种实现方式,参考 https://wiki.tools.ietf.org/html/rfc5802 https://tools.ietf.org/html/rfc7677 使用SCRAM-SHA256认证,仅通过抓包是无法破解密码的。 基于SCRAM-SHA256标准,我实现了一个cassandra的插件,放在了github上 https://github.com/johnyannj/cassandra-secure-plugin 欢迎使用

2018年10月14日 · 1 分钟

赵岩的博客全站HTTPS改造

互联网安全和个人隐私越来越被人们关注,不仅仅是电商等交易网站都实现了全站https,现在微博、百度以及大大小小的博客都实现了全站https。如果你的网站不是https的,火狐、chrome、IE浏览器都会在地址栏前方提示用户 你当前访问的网站是不安全的。 为了跟风,赵岩的博客今天起全站使用https。 为了实现全站HTTPS。我主要做了以下工作: 第一、HTTPS证书 https使用SSL传输协议,SSL之所以安全,是因为加密传输的。初始公钥由服务器传递给浏览器,为了保证公钥安全的传输到浏览器,并被浏览器认可,我们需要一个由第三方权威机构签名的证书。详细参考《HTTPS到底是如何保证通信安全的》 普通的单域名证书一年需要1000多元,我们自然不会去花这个钱的。阿里云代理的赛门铁克提供个人免费域名证书。可以直接申请。阿里证书申请 申请的时候选择“Symantec ”、“免费型”、“一个域名”。阿里云会要求DNS或者文件验证,证明你是域名的拥有者。整个申请过程10几分钟可完成。 第二、升级Nginx Nginx需要使用–with-http_ssl_module参数编译,确保支持https。为此我趁机会升级了下Nginx的版本到最新版本。 把你的证书pem文件和私钥key文件上传到服务器。 配置nginx.conf,监听443端口并加载证书。 原来监听的80端口,301转向443端口 server { listen 80; server_name zhaoyanblog.com; include black_list; rewrite ^(.*) https://$server_name$1 permanent; } server { listen 443; server_name zhaoyanblog.com; ssl on; ssl_certificate cert/xxx.pem; ssl_certificate_key cert/xxxx.key; ssl_session_timeout 5m; ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_prefer_server_ciphers on; ...... 第三、全站HTTPS 1、检查网站内有没有引用了别的网站的js。需要切成https地址。或者根据document.location.protocol自适应当前的访问协议。 比如:微博、百度统计、百度站长、百度联盟广告等等组件。 http://widget.weibo.com/weiboshow/index.php 改成 https://widget.weibo.com/weiboshow/index.php 2、检查是否直接使用了本站的http地址。改成相对路径。虽然已经配置了80端口301跳转。这样改会少一步对服务器的访问。 比如:/wp-content/uploads/2017/04/zhaoyanblog_2017-04-17_14-50-20.jpg 改成 /wp-content/uploads/2017/04/zhaoyanblog_2017-04-17_14-50-20.jpg 可以通过查看浏览器的调试信息,知道哪些访问的资源仍然是http的。 第四、通知百度进行HTTPS验证 在验证好全站已经使用https,并且访问http也可以301跳转到https。我们需要通知百度等搜索引擎进行https验证。因为搜索引擎在之前都是缓存我们的http地址。需要告知他我们切到https。避免导致收录的页面丢失。 直接登录百度站长,里面有个https验证页面,点击验证即可。 至此赵岩的博客已经实现全站https ...

2018年5月20日 · 1 分钟

关于level压缩策略的level0问题

Cassandra一开始是要写commitlog,当commitlog写到一定大小就会刷到一个sstable文件,再加上对于cassandra,删除也是一种写,这样下去sstable文件会越来越多。必须有一种机制来合并这些文件,并删除墓碑(标记为删除的记录),这种机制叫做compaction,先翻译为压缩。既然要合并文件,就要有合并策略。cassandra一开始只有size模式的压缩策略。后来增加了level压缩。 level压缩提高了读的性能,但是level压缩相比较size压缩更慢,因为它是要保证每个level都有一定数量的文件,新产生的文件都是level 0的状态,同时在执行的压缩任务是有限制的,当几个高level的文件在压缩的时候,可能导致level0的文件堆积。 level压缩需要保证低级别的level的文件较少,是为了提高查询的效率。 为了避免level0的文件因为大量写入而得不到压缩。cassandra采取了一种策略,就是level 0文件数目超过一定限制(默认32),就在level 0采用size压缩,通过合并快速减少 level 0文件数量,同时暂停高level的文件压缩。 这个设计在正常情况下是有好处的。但是当我们扩容一个节点的时候,新增节点的文件全部在level 0。 sstable level 12222 0 0 0 0 0 0 0 那么cassandra会的持续进行level 0的 size压缩。直到level 0的文件减少到32以下 sstable level 32 0 0 0 0 0 0 0 这样你会发现新扩节点会一开始产生一个超大文件,然后再拆分成个个小文件的现象。 问题是:如果你有6个500G的磁盘,而你的单节点数据是2T,那么你的节点会因为空间不足而挂掉。 解决这个问题有两种方法: 一种是磁盘做raid,搞成一个大磁盘。 一种是临时关闭level 0的size压缩,这又是cassandra的一个隐藏技能,在cassandra官方文档里你不会找到。就是启动的时候加禁用level 0 使用 size压缩的参数: ./cassandra -Dcassandra.disable_stcs_in_l0=true 注意这个参数从cassandra 2.0.10以后的版本才有。当解决了问题后建议把该参数还原。因为在 level 0采用size压缩,对于突发写入大量的数据的情况还是有好处的。 参考 https://issues-test.apache.org/jira/browse/CASSANDRA-6621

2018年5月6日 · 1 分钟

Cassandra压缩任务堆积如何处理?

当短时间内写入的数据太多,或者连续扩容多个节点,都有可能导致压缩任务堆积,压缩任务堆积会导致sstable太多,让该节点查询变慢,时延变大,一直累积下去,集群会变的很不稳定。解决方法如下: 加大压缩速度阈值 默认压缩阈值是16Mb/s,偏小,可以更改的大一点,这个参数是可以通过nodetool setcompactionthroughput xx进行修改,配置文件cassandra.yaml里的默认值(配置项是compaction_throughput_mb_per_sec),也建议修改到一个合适的值,否则某一天重启节点,又恢复到了默认值。 增加压缩线程 修改配置文件cassandra.yaml里的配置项concurrent_compactors,这个不能动态调整,需要重启生效,默认是2-8之间的一个值,取自数据盘和cpu个数的最小值,这个值一般不需要动,除非你是ssd的盘,可以适当的增加。 临时关闭gossip 如果只是其中一个节点压缩堆积,负载特别高,可以考虑先临时关闭这个节点的gossip,使用nodetool disablegossip命令。这样这个节点对于客户端而言就是DOWN的状态,客户端就不会发请求到该节点,但是集群内部之间通信正常,不会丢失数据。只要你不使用All一致性,是不会影响业务正常请求的。然后你可以把节点的压缩速度阈值调为0,也就是不限制速度,让它早点压缩完毕恢复正常。最后记得用enablegossip恢复。 临时忽略墓碑 这个方法不在cassandra的官方文档里,也没有出现在官方的changelist里。因为这是一个很危险的操作,墓碑不及时清除,会带来读操作性能问题。如果你确认短时间内不清除墓碑不会对你的业务场景产生影响,你可以尝试临时使用该方式,在压缩完成后恢复,不能长期使用。 cassandra在压缩的时候为了安全清除墓碑,会查找多个sstable文件,当压缩堆积,sstable很多的时候,压缩会变的相当缓慢。所以官方增加了这么一个彩蛋形式的配置项。这个配置项是一个环境变量,在启动的时候指定 ./cassandra -Dcassandra.never_purge_tombstones=true 注意这个配置项在2.1.15版本以后才有。

2018年3月7日 · 1 分钟

关于Cassandra的分段Repair

为什么要Repair Repair对Cassandra集群是极为重要的,因为频繁的数据删除以及机器Down掉(尽管有Hinted Handoff机制)都会可能导致数据不一致(多个副本之间)。在Cassandra日常维护中,我们要例行对集群进行Repair操作,使用nodetool的Repair命令。 Repair原理 Cassandra在Repair的操作分两个步骤: 第一: 创建Merkle tree Merkle tree是一个二叉树,二叉树最底层是要比较的数据块的hash值,父节点是两个子节点的hash值(=hash(hash1+hash2))。二叉树的高度是15,也就是说最底层有2^15=32768个叶子节点,对应有32768个数据块,如下图所示。 计算Merkle Tree的过程需要依赖磁盘IO。为了不影响业务,你可以限制压缩阈值(nodetool setcompactionthroughput),因为这个过程被称作validation compaction,体现在压缩任务里。 第二:比较Merkle Tree,找出差异进行数据传输。 为每个副本创建Merkle Tree以后,副本之间只要通过比较最顶端的hash是否一致,然后一层层比较下来,就可以找到不一致的那个数据库,然后进行数据传输进行修复即可。 合理分段Repair 上面的修复过程有个问题,就是Merkle Tree是存储在内存里的,所以Cassandra对高度进行了限制,只能有15层,数据只能分为32768数据块。那么这就限制了Merkle Tree的精度,假设一个节点有10万个分区key,每个数据块大约有30个,假设其中有1条数据不一致,那至少要传输30个分区key的数据。这是很浪费集群带宽和修复时间的(修复需要在gc_grace_seconds周期内完成,防止删掉的数据又出现) Cassandra的nodetool repair提供了分段Repair的参数,-st -et分别表示token段的范围,假设我们每次repair的数据正好有32768个分区key,那么我们就可以进行精确的修复,减少不必要的传输。当我们把所有的token小段repair完毕,就相当与我们把所有数据进行了repair。 那么问题来了,怎么样对token段进行细分呢? 每个cassandra节点都有个表叫 system.size_estimates(好像是从2.1.4版本开始),在里面记录了每个表在每个token段上大约有多少分区key(partitions_count)以及每个分区key的大小(mean_partition_size) CREATE TABLE system.size_estimates ( keyspace_name text, table_name text, range_start text, range_end text, mean_partition_size bigint, partitions_count bigint, PRIMARY KEY (keyspace_name, table_name, range_start, range_end) ) 你可以遍历所有的token段进行repair,遇到分区key较多的token段(大于32768),继续细分成多个子token段进行repair。

2018年2月25日 · 1 分钟

Cassandra的数据分布和副本(一致性hash原理)

一致性hash设计出来的目的是: 根据数据的hash值把数据分布在n个节点上,当新增一个节点或者删除一个节点后根据算法重新计算,可以保证大部分数据都分布在原来节点上,只需要移动少部分数据即可。 再具体一点,当删除一个节点,只要把属于这个节点上的数据移动到其它节点上,当增加一个节点,只要从其它节点上把属于这个节点的数据自动过来。而保持不动的节点之间不需要数据移动。 下面是具体原理: Cassandra的对数据key的hash值范围是long的最小值到long的最大值。每个节点默认负责这个单位内的256个范围。我们这里用4个范围代替。首先我们用一个圆(hash环)来表示整个hash范围。然后每个节点随机取4个点,假设我们当前有三个节点(A,B,C),如下图所示: 整个hash环就被分割为了12段,顺时针去看,A和B之间的hash段就属于A,B和C之间的hash段就属于B,以此类推。 一条数据的分区key的hash值落在哪个段里,就存到对应的机器上。 现在看如果要增加一个节点。我们同样在圆上增加随机的4个点。 ​这样整个圆被分割成了16个段,同样顺时针看,我们发现大多数分段仍然属于原来的节点,只有四个小段属于了新节点D,也就是说只要移动这四个小段的数据到新节点D上,我们就完成了数据的再均衡,完成了节点扩容。 同样的如果用想退役D节点,只要把对应的分段的数据再挪回去,就完成了缩容。而大部分数据不需要移动。 这个算法就叫做一致性hash算法。

2018年2月4日 · 1 分钟

Cassandra节点间通信协议(Gossip协议)

Gossip协议是一个点对点协议,Cassandra用于两个节点间相互交换他们的状态信息,以及他们所知道的其它节点的信息。Gossip线程每秒执行一次随机和集群内其它三个节点进行信息交换。交换的信息包括他们自己的信息,以及他们知道的其他节点的信息,所以所有节点很快就可以得到整个集群节点的信息。每个交换的gossip信息都有一个版本号,所以交换过程中较新的信息就会覆盖老的信息。 为了避免通信异常,请确保每个节点的种子节点列表都一样,这对于一个节点的第一次启动很重要。通常一个几点会通过gossip记住所有后面启动的节点。种子节点的设计除了引导新加入集群的新节点启动gossip进程以外,没有其它目的。种子节点不是单点故障,除了引导新节点启动外,没有任何其它特殊目的。 注意:在多数据中心的集群里,种子列表应该包含每个数据中心的至少一个节点(建议每个数据中心多于一个节点,用于容错),因为节点启动的时候还需要和另外数据中心的节点进行通信。不推荐把每个节点都作为种子节点,因为这增加了维护成本还降低了gossip性能。gossip方面的优化不是很重要,但是还是建议使用一个较小的种子列表(每个数据中心三个节点差不多了) 集群内节点故障检测和恢复都是通过gossip实现的. 故障检测是本节点通过gossip状态和历史信息确定集群中另外一个节点是挂掉了还是恢复了的一种方法。Cassandra从而避免把客户端的请求路由到不可达的节点上。(Cassandra还可以根据动态的策略,避免把消息发送到负载高的节点上)。 Gossip线程可以直接或者间接的跟踪其它节点的状态。(就是说这些节点状态的信息,可能是对应节点直接发给它的,也有可能是通过别的节点转发过来的二手,三手信息)。 Cassandra并不是通过一个固定的阈值来判断一个节点挂掉了。而且有一套动态的检测机制来计算每个节点的阈值,考虑了网络、负载、历史状态等因素。在gossip信息交换的过程中,每个节点都记录了从其它节点获取到的消息的时间窗口信息。配置文件里的phi_convict_threshold配置项可以调节失败检测的灵敏度。这个值越小,一个节点被标记为DOWN状态的几率就越大,值越大反而减少一个节点因为瞬间故障被标记为Down状态的概率。大多数情况下这个值保持默认就可以。但是在亚马逊云E2上可以把它提高到10~12,(亚马逊云经常有网络拥塞)。对于不稳定的网络环境(比如E2),提高到10~12可以减少故障误判。不推荐这个值大于12或者小于5。 节点故障可能是多种原因造成的,比如硬件故障,网络中断。节点中断往往是临时性的,但可能持续很长时间。节点中断通常并不意味着它永久脱离集群,所以cassandra并不会自动把故障的节点从集群hash环中删除掉,其它节点会定时的尝试联系这个节点以判断它是否恢复。如果想是永久性的操作,管理员必须使用nodetool工具或者从opscenter上明确的添加或者删除某个节点。 当一个节点从中断中恢复,他可能错过了很多写操作。一旦一个节被检测为故障中断,数据的其它副本所在的节点会帮它记录错过的写操作(记作hints)一段时间,前提是这个功能已配置启用。不过一个节点挂掉的时间太久,超过了max_hint_window_in_ms配置的值(默认3小时),hints就不再记录。那些挂掉的节点也有可能存储了一些未送达的hints。所以在恢复一个挂掉很久的节点后,请执行repair操作。而且,你应该定期执行noodtool repair命令以保证节点间数据一致性。 在cassandra中,数据的分布和副本要一起看,数据通过一个个的表组织起来,由一个主键确定数据存储在哪个节点上。副本就是一行数据的多个拷贝,当数据第一次写入的时候,其实我可以称为一个副本。 影响数据副本分布的因素包括: 虚拟节点:用于数据和物理节点映射关系。 分区:对集群中的数据进行分区 副本策略:确定每行数据的副本数 告密者: 对集群中节点拓扑关系的一种定义,副本策略根据它来放置副本。 Cassandra采用一致性hash算法来计算数据如何在节点上分布。使用一致性hash的目的是就是当增加或者移动一个节点的时候,只要移动很小的数据就可以完成数据的再均衡。 每条数据的第一个主键叫分区主键,分区主键的hash值落在哪个节点内,这条数据就分布在哪个节点。其它副本就落在hash环上的下一个节点上。

2018年2月4日 · 1 分钟

Cassandra如何选择压缩策略

SSTable的压缩是Cassandra的重要设计之一,墓碑的删除,数据的合并都依赖压缩才能完成,目前Cassandra有四种压缩策略,其中的一种已经被废弃。 压缩除了解决墓碑等根本问题外,选择不同的压缩策略也影响你的读写性能和集群稳定性。 至于如何选择压缩策略,官方有一系列问句帮你决定: 你存储的是和时间序列有关的数据吗? 如果是的,那么最佳的压缩策略就是TWCS,如果不是请继续后面的问题。 你的表是读多写少,还是写多读少? 如果读是写的两倍以上,特别是随机读的场景,建议用LCS策略,如果读和写差不多,用LCS引起的性能缺失和带来的好处相比,可能并不划算了。注意LCS策略很容易被大量的写击垮的。 你的表里的数据更新频繁吗? LCS的一个好处就是让有关联的数据集中在一组SSTable文件里。如果你的数据更新不频繁甚至是不更新的,用STCS也可以达到这样的目的,而不会有LCS带来的性能牺牲。 你是否需要可预测的读写? 这一段比较难以理解,博主用白话描述:你是否需要服务级别的读,就是对读的tps和时延是都有要求。如果有的话,即便是你的读写比很小,还是建议用LCS,因为LCS可以控制SSTable的数量和大小,从而保证稳定的读时延,当然写性能就会受到影响,不过这一点你可以通过扩节点的方式解决~ 你的表是否有大量的batch提交? 对于批量读和写,STCS的性能要优于LCS。批量提交不会引起太多的碎片文件,所以LCS的好处体现不出来,而且大量的批处理可能会击垮LCS策略的表。 你的磁盘空间是否有限? 在磁盘利用效率方面LCS要比STCS好,它只需要相比存储的数据10%的额外冗余空间,而STCS和DTCS需要50%以上的空间。注意DTCS已经废弃了。 你的系统IO是否到达瓶颈? LCS比DTCS和STCS产生更多的密集IO操作,切换到LCS带来的额外IO开销可能会抵消它所带来的优势。 通过上述问题,你是否知道自己应该选择什么样的压缩策略了吗?不要盲目做决定,建议你在正式上线前创建三个节点,设置你选择的策略,使用cassandra-stress对你的系统做个压力测试。

2017年11月26日 · 1 分钟

Cassandra有关系统参数九点优化

Cassandra不同于普通的应用程序,它是分布式数据库,它要大口吃内存,吃磁盘,吃CPU,所以机器要进行特殊的配置,以适应其需要。 第一:使用最新的64位的jdk8的最新发布版本。 第二:时钟同步,开启NTP服务,cassandra是分布式存储,就靠时间戳解决数据冲突,所以始终必须同步 第三:TCP参数设置 在低带宽环境下,防火墙会检测闲置的连接并关闭,为了保护节点之间,或者多个DC节点之间的连接,建议如下配置系统参数 sudo sysctl -w net.ipv4.tcp_keepalive_time=60 net.ipv4.tcp_keepalive_probes=3 net.ipv4.tcp_keepalive_intvl=10 设置这个就是可以快速的发现底层的TCP连接是否已经关闭,它间隔60秒开始探测3次,每次探测间隔10秒,也就是说最多在60+3*10=90秒内就可以检测到连接被中断。 为了支撑上千个数据库连接,还建议修改以下参数 sudo sysctl -w net.core.rmem_max=16777216 net.core.wmem_max=16777216 net.core.rmem_default=16777216 net.core.wmem_default=16777216 net.core.optmem_max=40960 net.ipv4.tcp_rmem=4096 87380 16777216 net.ipv4.tcp_wmem=4096 65536 16777216 为了让参数永久生效,记得把它们写入系统配置文件/etc/sysctl.conf里 第四:禁用CPU动态跳频功能。 最近的linux系统增加了一个新特性,就是可以动态调整CPU频率,就是在机器低负载的时候,可以降低CPU频率,以达到降低功耗的目的。 这种动态调频功能会影响cassandra数据库的吞吐量。建议禁用,让CPU一直维持恒定的频率输出,尽管这很耗电,但是保证你的数据库的吞吐量。 禁用方式: for CPUFREQ in /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor do [ -f $CPUFREQ ] || continue echo -n performance > $CPUFREQ done 第五:禁用zone_reclaim_mode 官方建议禁用,这个是关于多核CPU使用NUMA架构,分别访问内存,内存回收方面的一个参数 这个参数的解释,可以参考: http://linuxinsight.com/proc_sys_vm_zone_reclaim_mode.html 这里面有一句话,当你的机器用作文件服务器,或者你的大部分内存需要用于系统文件缓存的时候,你需要禁用这个功能。 我们的Cassandra就相当于文件服务器,它对IO是依赖的,它需要系统内存用于大量缓存DB文件。所以要禁用这个功能。 echo 0 > /proc/sys/vm/zone_reclaim_mode Cassandra官方描述了如果不禁用这个参数带来的后果: 1、随机CPU尖峰带来时延增加,吞吐量增加。 2、程序假死,什么也不做。 3、一些突然发生又消失的莫名异常。 4、重启机器,可能在一段时间内不再出现异常。 第六:资源限制放开。 cassandra会使用很多内存,很多连接,很多文件,所以一律放开。 <cassandra_user> - memlock unlimited <cassandra_user> - nofile 100000 <cassandra_user> - nproc 32768 <cassandra_user> - as unlimited ...

2017年11月21日 · 1 分钟

Cassandra的jvm内存设置多大合适

cassandra是java写的程序,java写的程序难以避免会遇到GC的问题,第一个问题就是jvm的内存设置多大合适,这往往是让人很纠结的事情。 以下来自官方建议: 首选是GC类型如何选择 推荐G1 GC有以下原因: 1、内存可以从14GB到64GB,G1在大内存上比CMS表现好,因为G1首选会扫描那些堆内区域包含垃圾对象比较多,并同时进行堆压缩,而CMS在执行GC的时候需要停止应用。 2、系统的负载是个变量,也就是说系统每个时间都在执行不同的线程操作。 3、CMS在java9以后就会被废弃 4、G1是很容易配置的 5、G1是一种自我优化的GC 6、你只要设置MAX_HEAP_SIZE就行了。 当然G1 GC这种分析会导致一定时延。 CMS通过在以下情形下被推荐使用: 1、你有足够的时间和专业知识来手动优化调试垃圾手机。 注意当数据库内存里保持了更多的系统元数据的时候,增加更大的内存给jvm,会因为GC而导致性能下降。 2、堆大小不超过14GB. 3、系统负载是固定的,也就是说集群一致在执行相同的工作。 4、环境需要更低的时延。 备注:不建议在java7下使用G1,因为G1在java7下有个bug关于类卸载的问题,在java7里PermGen会被一直填满,直到发生一个full GC。 其次是内存大小如何设置 你可能试图把java的内存设置为接近系统的RAM大小,显然这是不可能的,因为这会干扰操作系统的页面缓存的操作。操作系统把频繁访问的数据保存到内存里,也就是操作系统的页面缓存,这个是很有用的。适当调整操作系统的页面缓存通常比使用cassandra的row cache还好。 cassandra会基于以下公式,自动计算最堆内存(MAX_HEAP_SIZE): max(min(1/2RAM, 1024M), min(1/4RAM, 32G)) 对于生产环境,我们提供以下指导原则: 1、堆内存一般在操作系统内存的四分之一和二分之一之间 2、不要把所有的内存都给jvm,因为内存还要用于堆外缓存以及操作系统缓存。建议在优化GC的时候始终开启GC日志。 3、针对每个配置项的变化进行调整和测试 4、启用GC的并行处理,特别是使用cassandra企业版的索引检索。 5、GCInspector类的日志会对超过200ms的GC,打印日志。如果这样的GC频繁发生,或者需要很长的时间才能完成GC,那么表示当前压力已经超过GC能力范围,除了优化GC选项以外,其它的措施还包括扩容节点,降低缓存大小等。 6、如果是使用的G1 GC。Datastax官方建议最大内存MAX_HEAP_SIZE越大越好,可以到64GB. MAX_HEAP_SIZE的大小设置根据使用的GC类型而定: 1、对于超过8C256G内存的机器, 使用G1 GC建议MAX_HEAP_SIZE在14G到64GB之间 2、对于超过8C256G内存的机器, 使用CMS GC建议MAX_HEAP_SIZE不要超过14GB 3、其它较老的机器,配置典型值8G 对于CMS,你可能还要优化HEAP_NEWSIZE(新生代的堆大小) Cassandra的计算原则是 min(100M* cpu核心数, 1/4 MAX_HEAP_SIZE) 总之:HEAP_NEWSIZE越大停顿时间越长,HEAP_NEWSIZE越小可能更频繁,这个过程更加昂贵。 博主建议 不要再纠结,用jdk8,G1 GC,内存在1/4ram和1/2ran之间,越大越好,不要超过64G。

2017年11月19日 · 1 分钟