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 分钟

Mysql是如何做到安全登陆

首先Mysql的密码权限存储在mysql.user表中。我们不关注鉴权的部分,我们只关心身份认证,识别身份,后面的权限控制是很简单的事情。 在mysql.user表中有个authentication_string字段,存储的是密码的两次sha1值。 你可以用下面的语句,验证和mysql.user表中存储的是一致的。 select sha1(UNHEX(sha1(‘password’))) 以上就是服务端关于密码的存储,接下来是认证过程。 Mysql采用的是一种challenge/response(挑战-应答)的认证模式。 第一步:客户端连接服务器 第二步:服务器发送随机字符串challenge给客户端 第三步:客户端发送username+response给服务器 其中response=HEX(SHA1(password) ^ SHA1(challenge + SHA1(SHA1(password)))) 第四步:服务器验证response。 服务器存储了SHA1(SHA1(password))) 所以可以计算得到SHA1(challenge + SHA1(SHA1(password)))) 那么SHA1(password)=response^ SHA1(challenge + SHA1(SHA1(password)))) 最后再对SHA1(password)求一次sha1和存储的数据进行比对,一致表示认证成功。 我们分析它的安全性: 1、抓包可以得到response,但是每次认证服务器都会生成challenge,所以通过抓包无法构造登陆信息。 2、数据库内容被偷窥,数据库记录的是sha1(sha1(password)),不可以得到sha1(password)和明文密码,所以无法构造response,同样无法登陆。 当然如果被抓包同时数据库泄密,就可以得到sha1(password),就可以仿冒登陆了。 这种认证方式其实是有一个框架标准的,叫做SASL(Simple Authentication and Security Layer ),专门用于C/S模式下的用户名密码认证。原理就是服务器发送一个挑战字challenge给客户端,客户端返回的response证明自己拥有密码,从而完成认证的过程,整个过程不需要密码明文在网络上传输。 基于SASL协议有很多实现,mysql的就是模仿的CRAM-MD5协议,再比如SCRAM-SHA1协议,是mongdb、PostgreSQL 使用的认证方式。在JDK中专门有一套SASL的API,用于实现不同的SASL认证方式。

2017年11月11日 · 1 分钟

[新闻]华为荣耀9要来了

日前,华为官方宣布,荣耀9将在6月12日上海东方体育中心正式发布,其代言人为胡歌。 还记得美得与众不同的荣耀8吗? 从荣耀掌门人赵明的微博中得知,荣耀9将作为魅海蓝正宗继承者,作为荣耀年度美学旗舰产品发布。这样看来十分让人期待。 官方可靠谍照:

2017年6月10日 · 1 分钟

[翻译]关于Cassandra中的删除和墓碑(七)

单SSTable压实 单SSTable压实是在cassandra1.2引入的,是由Jonathan Ellis在CASSANDRA-3442最新提出来的: 在Size压实模式下,你可能会产生很大的SSTable,很少被压实,但是有很多过期的数据在里面,我们在这种情况下可能浪费了大量的磁盘空间。 就像我们上面提到的,压实的目的就是墓碑的剔除,在一定的场景下,压实操作并没有很好的剔除墓碑。不仅仅是这里提到的Size模式的压实(STCS),所有的压实模式都有这种情况。一些SSTable文件很久才会被压一次或者很长时间都会有重叠的SSTables(译者注:表示不能合并ROW)。这也是为什么,时至今天,每个压实模式都会有一堆的配置项用于调节墓碑的剔除。 tombstone_threshod: 这个配置项的作用就是Jonathan Ellis 在2011年提出的: 如果一个SSTable在它的元数据信息里保存它含有的ttl记录的统计数据,我们就可以当过期数据超过20%的时候,进行一次单SSatble压实操作。 所以当墓碑占有率超过这个值(默认等于0.2,也就是20%)的时候,这个选项就会触发一次单SStable压实。需要注意的是,那些真正可以被剔除的墓碑经常小于估值,因为计算这个墓碑占有率的时候,并未考虑gc_grace_secods参数。 tombstone_compaction_interval: 这个选项是在CASSANDRA-4781中被引入,目的是为了解决一个死循环问题,当一个SSTable文件的墓碑占有率达到了触发一次单SStable压实的操作,但是由于和别的SStable有重叠,导致无法清除墓碑。因为我们要删除一个文件的所有碎片,以防止僵尸数据产生。这种情况下一些SStable的压实操作可能无休止的进行下去。既然一个SStable里还有的墓碑率是个估值,那么我这个选项就用于限制两次单SStable压实操作的最小间隔时间,默认是1天。 unchecked_tombstone_compaction:是Paulo Motta在CASSANDRA-6563引入的。在这个问题单里他描述了单个SSTable压实的历史和他引入这个参数的原因,非常有趣。我是无法更好的去解释它。(译者注:意思是你可以直接去看问题单。) 注意此选项配置为true以后,就会出发一个SStable一天一次的压实(tombstone_compaction_interval默认),只要墓碑占有率(估计值)高于0.2(20%是墓碑,这个是tombstone_threshold默认值),最坏的情况就是即便是没有任何墓碑是可以被剔除的也会执行一次压实。 所以最好是多投入一些资源(多加一些机器?)希望让墓碑的剔除更好的进行。 推荐做法:当一个DC已经在删除墓碑上有麻烦了,立即使用下这个参数,应该是值得的。我在使用这个选项上,已经有一些很成功的经验以及一些不是很糟糕的经验。相反的也有一些很少场景,这个选项实际上并没有什么作用。我甚至有一次设置这个选项为true除非手动压缩。把一些磁盘已经100% 马上挂掉的机器恢复了正常。 要修改这些配置的时候,先查看表的描述。然后重新指定整个压实策略,以避免一些意外。假设我想修改tlp_lab库里tombstones表的压实参数,我会这样做: MacBook-Pro:~ alain$ echo "DESCRIBE TABLE tlp_lab.tombstones;" | cqlsh CREATE TABLE tlp_lab.tombstones ( fruit text, date text, crates set, PRIMARY KEY (fruit, date) ) WITH CLUSTERING ORDER BY (date ASC) AND bloom_filter_fp_chance = 0.01 AND caching = {'keys': 'ALL', 'rows_per_partition': 'NONE'} AND comment = '' AND compaction = {'class': 'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy', 'max_threshold': '32', 'min_threshold': '4'} AND compression = {'chunk_length_in_kb': '64', 'class': 'org.apache.cassandra.io.compress.LZ4Compressor'} AND crc_check_chance = 1.0 AND dclocal_read_repair_chance = 0.1 AND default_time_to_live = 0 AND gc_grace_seconds = 864000 AND max_index_interval = 2048 AND memtable_flush_period_in_ms = 0 AND min_index_interval = 128 AND read_repair_chance = 0.0 AND speculative_retry = '99PERCENTILE'; 然后我会复制这些压实选项,并修改它: ...

2017年6月9日 · 2 分钟

[翻译]关于Cassandra中的删除和墓碑(六)

墓碑清除 只有在local_delete_time + gc_grace_seconds以后墓碑才会在压实的时候完全清除掉。记住,这是假定所有节点都在gc_grace_seconds时间内repair过了,以保证墓碑在所有节点上都正确分布,这是为了防止删除的数据再出现,上面已经说过了。 gc_grace_seconds参数是墓碑在磁盘上存在的最短时间。我们需要保证所有的副本都收到了这个删除操作,并且写入了墓碑,从而避免僵尸数据的问题。为了达到这个目的,我们唯一的方法就是全量repair。在gc_grace_seconds以后,墓碑最终会请清除,如果其中一个节点没有写入这个墓碑,我们就会进入上面描述的数据又出现的境地。TTL没有影响,因为没有节点可以保留数据而错过ttl,它是一个原子操作,数据和ttl是一条记录。任何有数据的节点都知道什么时候必须删除数据。 另外,为了删除数据和墓碑,还有一些安全守则需要Cassandra节点必须遵守。我们需要一行数据或者一个分区key的所有的片段数据以及墓碑都要在同一个压实中。假设一个压实操作包含1-4个文件,如果一些数据在文件5上面,墓碑被清除后,我们仍需要留下一个标记数据(译者注:墓碑),表示文件5里的数据被清除了,否则文件5里的数据又会回来了(成为僵尸数据)。 这些条件有时候让删除墓碑成为一件很复杂的事情,它经常给Cassandra的使用者带来麻烦。墓碑不被清除意味着占用更多的磁盘,更慢的读,以及更多的repair工作,高概率的GC压力,更多的资源利用等等。当你的sstable的墓碑占到一个很高的的比率(90%的数据都是墓碑),读取一个值或者一段相关的数据会变的相当困难,存储的成本也越来越高。这些问题最终会导致磁盘空间耗尽。 很多使用情况下会导致数据删除(TTL或者delete操作),作为Cassandra的使用者我们必须克制,控制这些事情。 再次回到我们这个例子,我重启了这个节点在很多天以后(>10天,gc_grace_seconds的默认值)。Cassandra重新打开压实过的mb-14-big文件,它立马又进行了压实操作。 MacBook-Pro:tombstones alain$ grep ‘mb-14-big’ /Users/alain/.ccm/Cassa-3.7/node1/logs/system.log DEBUG [SSTableBatchOpen:1] 2016-06-28 15:56:17,947 SSTableReader.java:482 - Opening /Users/alain/.ccm/Cassa-3.7/node1/data/tlp_lab/tombstones-c379952033d311e6aa4261d6a7221ccb/mb-14-big (0.103KiB) DEBUG [CompactionExecutor:2] 2016-06-28 15:56:18,525 CompactionTask.java:150 - Compacting (166f61c0-3d38-11e6-bfe3-e9e451310a18) [/Users/alain/.ccm/Cassa-3.7/node1/data/tlp_lab/tombstones-c379952033d311e6aa4261d6a7221ccb/mb-14-big-Data.db:level=0, ] 此时,gc_grace_seconds已经过去了,墓碑有条件被清除了,所以所有的墓碑都被清除了,最后表里没有任何数据了,数据目录最终也是空的: MacBook-Pro:tombstones alain$ ll /Users/alain/.ccm/Cassa-3.7/node1/data/tlp_lab/tombstones-c379952033d311e6aa4261d6a7221ccb/ total 0 drwxr-xr-x 3 alain staff 102 Jun 28 15:56 . drwxr-xr-x 3 alain staff 102 Jun 16 20:25 .. MacBook-Pro:tombstones alain$ 如果墓碑在所有副本都都正确存在,我们就会有完全一致的删除操作,删除的数据就不会再出现。而且我们还可以释放一些磁盘空间,让其他数据的读变的更容易,尽管为了证明这个事情,我的例子有点傻,但最后这个表是完全变空了。 监控墓碑比率和到期时间 因为Cassandra的设计,当我们删除数据或者使用ttl的时候很正常的就产生了墓碑。当然这个是我们必须要控制的。 使用sstablemetadata我们可以指定一个sstable的墓碑占有率,以及一个大概的墓碑清除时间分布情况。 alain$ SSTablemetadata /Users/alain/.ccm/Cassa-3.7/node1/data/tlp_lab/tombstones-c379952033d311e6aa4261d6a7221ccb/mb-14-big-Data.db – Estimated droppable tombstones: 2.0 – Estimated tombstone drop times: 1466154851: 2 1466156036: 1 1466156332: 1 – ...

2017年3月24日 · 1 分钟

[翻译]关于Cassandra中的删除和墓碑(五)

减轻墓碑带来的麻烦 好了,现在我们已经明白为什么我们要用墓碑,我们对墓碑也有一个大致的了解了。现在让我们看看墓碑会引起哪些潜在的麻烦,我们可以采取哪些措施来减轻这些麻烦。 首先一个很显而易见的事情就是墓碑没有让数据被删掉,反而增加了存储。我们需要删除这些墓碑以腾出磁盘空间,并且限制读出无用数据的大小,以降低时延和提高资源利用率。这个事情就发生在接下来你看到的压实的过程。 压实(Compactions) 当我们读取某一行数据的时候,为了读取到这一行数据的所有片段,我们翻阅的SSTables阅读,读时延就越大。因此我们有必要把这些片段通过压实的过程把他们合并,以获得更低的读时延。这个过程包括把合适的目标也清除掉,如我所愿的持续释放可用的空间。 压实的过程是通过合并来自多个sstable的row片段,去删除满足一定条件的墓碑。有些条件是在表的schema中指定的,而且是可以优化可调节的,比如gc_grace_seconds参数,有些条件是cassandra内部的,代码里写死的,这是为了保证数据持久化和一致性。要保证没有参与当前压实的sstable(重叠sstables)里没有新的数据片段,这是防止墓碑被清掉以后,数据又出现成为僵尸数据的必要条件。 再看上面的例子,经过删除和flush以后,表数据目录大致如下: alain$ ll /Users/alain/.ccm/Cassa-3.7/node1/data/tlp_lab/tombstones-c379952033d311e6aa4261d6a7221ccb/ total 360 drwxr-xr-x 43 alain staff 1462 Jun 17 11:39 . drwxr-xr-x 3 alain staff 102 Jun 16 20:25 .. drwxr-xr-x 2 alain staff 68 Jun 16 17:05 backups -rw-r–r– 1 alain staff 43 Jun 17 11:13 mb-10-big-CompressionInfo.db -rw-r–r– 1 alain staff 43 Jun 17 11:13 mb-10-big-Data.db -rw-r–r– 1 alain staff 10 Jun 17 11:13 mb-10-big-Digest.crc32 -rw-r–r– 1 alain staff 16 Jun 17 11:13 mb-10-big-Filter.db -rw-r–r– 1 alain staff 9 Jun 17 11:13 mb-10-big-Index.db -rw-r–r– 1 alain staff 4701 Jun 17 11:13 mb-10-big-Statistics.db -rw-r–r– 1 alain staff 59 Jun 17 11:13 mb-10-big-Summary.db -rw-r–r– 1 alain staff 92 Jun 17 11:13 mb-10-big-TOC.txt -rw-r–r– 1 alain staff 43 Jun 17 11:33 mb-11-big-CompressionInfo.db -rw-r–r– 1 alain staff 53 Jun 17 11:33 mb-11-big-Data.db -rw-r–r– 1 alain staff 9 Jun 17 11:33 mb-11-big-Digest.crc32 -rw-r–r– 1 alain staff 16 Jun 17 11:33 mb-11-big-Filter.db -rw-r–r– 1 alain staff 9 Jun 17 11:33 mb-11-big-Index.db -rw-r–r– 1 alain staff 4611 Jun 17 11:33 mb-11-big-Statistics.db -rw-r–r– 1 alain staff 59 Jun 17 11:33 mb-11-big-Summary.db -rw-r–r– 1 alain staff 92 Jun 17 11:33 mb-11-big-TOC.txt -rw-r–r– 1 alain staff 43 Jun 17 11:33 mb-12-big-CompressionInfo.db -rw-r–r– 1 alain staff 42 Jun 17 11:33 mb-12-big-Data.db -rw-r–r– 1 alain staff 10 Jun 17 11:33 mb-12-big-Digest.crc32 -rw-r–r– 1 alain staff 16 Jun 17 11:33 mb-12-big-Filter.db -rw-r–r– 1 alain staff 9 Jun 17 11:33 mb-12-big-Index.db -rw-r–r– 1 alain staff 4611 Jun 17 11:33 mb-12-big-Statistics.db -rw-r–r– 1 alain staff 59 Jun 17 11:33 mb-12-big-Summary.db -rw-r–r– 1 alain staff 92 Jun 17 11:33 mb-12-big-TOC.txt -rw-r–r– 1 alain staff 43 Jun 17 11:39 mb-13-big-CompressionInfo.db -rw-r–r– 1 alain staff 32 Jun 17 11:39 mb-13-big-Data.db -rw-r–r– 1 alain staff 9 Jun 17 11:39 mb-13-big-Digest.crc32 -rw-r–r– 1 alain staff 16 Jun 17 11:39 mb-13-big-Filter.db -rw-r–r– 1 alain staff 11 Jun 17 11:39 mb-13-big-Index.db -rw-r–r– 1 alain staff 4591 Jun 17 11:39 mb-13-big-Statistics.db -rw-r–r– 1 alain staff 65 Jun 17 11:39 mb-13-big-Summary.db -rw-r–r– 1 alain staff 92 Jun 17 11:39 mb-13-big-TOC.txt -rw-r–r– 1 alain staff 43 Jun 17 11:12 mb-9-big-CompressionInfo.db -rw-r–r– 1 alain staff 127 Jun 17 11:12 mb-9-big-Data.db -rw-r–r– 1 alain staff 10 Jun 17 11:12 mb-9-big-Digest.crc32 -rw-r–r– 1 alain staff 16 Jun 17 11:12 mb-9-big-Filter.db -rw-r–r– 1 alain staff 20 Jun 17 11:12 mb-9-big-Index.db -rw-r–r– 1 alain staff 4740 Jun 17 11:12 mb-9-big-Statistics.db -rw-r–r– 1 alain staff 61 Jun 17 11:12 mb-9-big-Summary.db -rw-r–r– 1 alain staff 92 Jun 17 11:12 mb-9-big-TOC.txt ...

2017年3月24日 · 4 分钟

[翻译]关于Cassandra中的删除和墓碑(四)

让我们现在看看各种类型的删除: cell删除 在cassandra存储引擎里,一指定行里面的一列就叫做cell。 删除某一行的某一个cell如下: DELETE crates FROM tlp_lab.tombstones WHERE fruit=‘apple’ AND date =‘20160617’; 这一行的crates列就会显示为“null”: alain$ echo “SELECT * FROM tlp_lab.tombstones LIMIT 100;” | cqlsh fruit | date | crates ———+———-+—————– apple | 20160616 | {1, 2, 3, 4, 5} apple | 20160617 | null pickles | 20160616 | {6, 7, 8} (3 rows) 执行flush以后,我们会得到一个新的sstable在磁盘上: mb-6-big alain$ ll /Users/alain/.ccm/Cassa-3.7/node1/data/tlp_lab/tombstones-c379952033d311e6aa4261d6a7221ccb/ total 144 drwxr-xr-x 19 alain staff 646 Jun 16 21:12 . drwxr-xr-x 3 alain staff 102 Jun 16 20:25 .. drwxr-xr-x 2 alain staff 68 Jun 16 17:05 backups -rw-r–r– 1 alain staff 43 Jun 16 20:53 mb-5-big-CompressionInfo.db -rw-r–r– 1 alain staff 127 Jun 16 20:53 mb-5-big-Data.db -rw-r–r– 1 alain staff 10 Jun 16 20:53 mb-5-big-Digest.crc32 -rw-r–r– 1 alain staff 16 Jun 16 20:53 mb-5-big-Filter.db -rw-r–r– 1 alain staff 20 Jun 16 20:53 mb-5-big-Index.db -rw-r–r– 1 alain staff 4740 Jun 16 20:53 mb-5-big-Statistics.db -rw-r–r– 1 alain staff 61 Jun 16 20:53 mb-5-big-Summary.db -rw-r–r– 1 alain staff 92 Jun 16 20:53 mb-5-big-TOC.txt -rw-r–r– 1 alain staff 43 Jun 16 21:12 mb-6-big-CompressionInfo.db -rw-r–r– 1 alain staff 43 Jun 16 21:12 mb-6-big-Data.db -rw-r–r– 1 alain staff 10 Jun 16 21:12 mb-6-big-Digest.crc32 -rw-r–r– 1 alain staff 16 Jun 16 21:12 mb-6-big-Filter.db -rw-r–r– 1 alain staff 9 Jun 16 21:12 mb-6-big-Index.db -rw-r–r– 1 alain staff 4701 Jun 16 21:12 mb-6-big-Statistics.db -rw-r–r– 1 alain staff 59 Jun 16 21:12 mb-6-big-Summary.db -rw-r–r– 1 alain staff 92 Jun 16 21:12 mb-6-big-TOC.txt ...

2017年3月23日 · 4 分钟

[翻译]关于Cassandra中的删除和墓碑(三)

保存墓碑(原文Tombstones to the rescue 墓碑营救?) 在Cassandra语境中,墓碑是一种特殊的数据和普通数据一样存储,一个删除操作,就是写入一个墓碑。当Cassandra读取数据的时候,它会合并这些内存里或者磁盘上写入的数据行。然后使用一种最新写入胜出(LWW)算法选择出正确的数据,不管它是个标准写入的数据,还是一个墓碑。 举例: 我们看下接下来的例子,背景是Cassandra 3.7集群,有3个节点(通过ccm创建的,译者注:ccm是个脚本程序可以快速的删除创建一个小Cassandra集群,github地址是:https://github.com/pcmanus/ccm) CREATE KEYSPACE tlp_lab WITH replication = {‘class’: ‘NetworkTopologyStrategy’, ‘datacenter1’ : 3}; CREATE TABLE tlp_lab.tombstones (fruit text, date text, crates set<int>, PRIMARY KEY (fruit, date)); 插入一些数据,每天创建一些水果(译者注:表里的字段的含义),如下: INSERT INTO tlp_lab.tombstones (fruit, date, crates) VALUES (‘apple’, ‘20160616’, {1,2,3,4,5}); INSERT INTO tlp_lab.tombstones (fruit, date, crates) VALUES (‘apple’, ‘20160617’, {1,2,3}); INSERT INTO tlp_lab.tombstones (fruit, date, crates) VALUES (‘pickles’, ‘20160616’, {6,7,8}) USING TTL 2592000; 下面就是我们存储的数据: alain$ echo “SELECT * FROM tlp_lab.tombstones LIMIT 100;” | cqlsh ...

2017年3月21日 · 3 分钟

[翻译]关于Cassandra中的删除和墓碑(二)

分布式删除的难题 考虑上面的情况,强一致性是必须的,让我们暂且忘掉墓碑这个东西,假设cassandra删除数据不使用墓碑。如果一次删除操作在一个节点上失败了(总共3个节点,副本为3, RF=3).整个删除操作仍然被认为成功的(因为有两个节点应答成功,使用CL.QUORUM一致性)。接下来如果读发生在该节点上就会变的不明确,因为结果返回是空,还是返回数据,没有办法确定哪一种是正确的。Cassandra总是任务返回数据是对的,那就会发生删除的数据又出现了的事情,这些数据可以叫"僵尸"或者"鬼",并且他们的表现是不可预见的 注意:这个问题没有完全解决,即便使用了墓碑,所以假设你的集群有删除操作的话我们还要有如下操作: Cassandra运维人员必须在每个gc_grace_seconds周期内对整个集群进行repair操作。 从一个Cassandra节点的视角看待删除 Cassandra使用一旦写入就不再改变的文件来存储数据,像前面描述,墓碑的目的就是为了解决从这样的系统中删除数据的困难的。 Cassanda的一个特种就是使用了一种日志结构合并树(LSM tree),然而大多数关系型数据库(RDBMS)是使用的B树(B-tree)。这样说你可能更容易理解:记住Cassandra写的时候总是往后追加数据,读的时候才会综合这些写入片段,选择每列的最大版本号去返回。 LSM Trees还有一个属性是数据写入文件中就不可以更改(这些文件在Cassandra中叫做SSTables)。正如最初讨论的那样,显然对于这样一个系统,删除只能通过一种特殊的写来实现。读的时候根据墓碑的时间戳,忽略小于这个时间戳之前插入的数据。

2017年3月20日 · 1 分钟

[翻译]关于Cassandra中的删除和墓碑(一)

从像apache cassandra这样的系统中,删除分布式主从复制的数据远比关系型数据库要复杂的多。当我们想到cassandra的数据是存在磁盘上的多个文件中,这个删除的过程变的超级有趣。在这样一个系统中,需要写入一个被称作墓碑(tombstone)的标记,用于记录一个删除操作,表示之前的值被删掉了。尽管你可能觉得这很不正常,或者难以理解(特别是当你意识到删除操作竟然是要占空间存储的),我们将用这篇博客,使用一些例子来解释这其中究竟发生了什么。 Cassandra:可用性和一致性的考虑 在我们深入细节之前,我们需要快速回顾一下Cassandra作为一个分布式系统是怎么工作的,特别是关于可用性和一致性。这对于我们等会解释分布式删除,以及一些潜在问题,非常有必要。 可用性:为了保证Cassandra可以复制数据,也就是说根据副本因子,存储的每一条数据都有多份拷贝。副本因子定义了每个keyspace(库的概念)在每个DC(数据中心)中的拷贝个数。通过配置,每个拷贝可以分布在不同的机架上,只要你有足够的机架,并且通过配置机架策略让系统考虑这些因素。有了这个,当任何一个节点(或者是一个机架,再说一遍,这个取决于你是否进行了配置)挂了,数据仍然可以通过其它副本进行读取。 一致性:为了确保读取数据的强一致性,我们必须遵循下面的原则: CL.READ = 读一致性. 从至少多个节点得到读响应,我们才承认它是一个成功的操作. CL.WRITE = 写一致性,同上. RF = 副本因子(个数) 要满足 CL.READ + CL.WRITE > RF,只有这样,我们才能保证至少有一个写入数据的节点被读到(译者注:好有道理) 通常的例子:我们考虑下面的设置: RF = 3 CL.READ = QUORUM = RF/2 + 1 = 2 CL.WRITE = QUORUM = RF/2 + 1 = 2 CL.READ + CL.WRITE > RF –> 4 > 3 这样的配置,就有很高的可用性,没有单点故障(SPOF),我们可以承担挂掉一个机器的风险,因为我们可以保证有一个写数据的节点可以读到,再加上最新者写入者胜出(LWW)算法(译者注:记录以写入时间戳最新的为准),就可以知道哪个节点的数据是正确的。 先把这种配置和做法记在脑子里,我们看一些执行删除的例子。

2017年3月18日 · 1 分钟

[翻译]Cassandra经常被问到的问题(三)

14、是不是单个seed意味着单点故障? 即便没有seed节点,集群也可以运行和重启,但是不能再往集群里增加节点。还是推荐在生产系统中配置多个种子节点。 15、为什么不可以在jconsole里调用某个jmx方法呢? 一些JMX操作的参数是个数组,而Jconsole并不支持数组型参数。对于那些不能用jconsole调用的操作(在jconsole里点击按钮无效)。有需要自己写一个JMX客户端去调用,或者使用一个支持数组的jmx监控工具。 16、为什么我会在日志文件里看到 “… messages dropped …“这样的信息? 这是cassandra在面对超出自己处理能力的请求时,为了保护自己做出的流控措施。 一个节点接收到其它节点发送过来的消息,但是在他们合适的超时时间内不能得到处理(具体参考 read_request_timeout, write_request_timeout等配置项)。就会被丢弃,而不是处理(因为接受用户请求的节点也就是协调节点不会再等这个响应返回) 对于写,这意味着它的请求不会被写入所有的副本,这个一致性将会被读修复、hints或者是人工修复等方式修复。因为这,一个写操作返回给客户端的结果就是超时的。 对于读,意味着一个读请求可能没有完成。负载流控是cassandra架构的一部分,如果这个问题一直持续下去,这标志着你的节点或者集群已经超载了。 17、Cassandra因为java.lang.OutOfMemoryError: Map failed挂掉了 如果cassandra挂掉的时候输出“Map failed”的消息,表示操作系统不允许java锁定更多的内存。在linux里,内存锁定是有限制的,你可以通过/proc//limits确认,并提高它(比如适应ulimit命令)。还有vm.max_map_cout参数。注意debian安装包会自动为你调整这些参数。 18、如果再同一时刻发生两次更新会发生什么? 更新顺序必须是可交换的,因为他们很有可能到达不同副本的顺序是不一样的。只要cassandra有一个确定的方法选出这个赢家(相同的时间戳),那么这在其它节点也是一样的,这是一个重要的实现细节。也就是说,对于相同时间戳的操作,Cassandra遵循以下两个原则:第一:删除要优先于更新和插入,第二:如果两个都是更新,那个在语法上比较大的更新会被选中。 19、为什么在加入一个新节点的时候,会有Stream failed错误? 两个可能性: GC可能导致的长时间暂停可能会扰乱传输进程 在后台执行的压缩会导致传输时间太长从而TCP连接断开。 对于第一种情况,建议在应用中经常的进行GC优化, 第二种情况,你需要设置系统的TCP keepalive参数短一些(linux中默认是很长的),尝试执行下面的语句: sudo /sbin/sysctl -w net.ipv4.tcp_keepalive_time=60 net.ipv4.tcp_keepalive_intvl=60 net.ipv4.tcp_keepalive_probes=5 如果要让这些配置永久有效,需要把他们加入到/etc/sysctl.conf文件中。 注意:GCE(Google的云服务吧)的防火墙经常切断TCP连接,当一个连接超过10分钟不活动的话。这种情况强烈推荐执行上述命令。

2017年3月11日 · 1 分钟

[翻译]Cassandra经常被问到的问题(二)

9 我可以通过批量提交加速我的大量写入吗? 不,使用批量提交只会带来延迟尖峰,使用异步的INSERT来代替,或者使用真正的“批量载入” 对同一个分区key的批量更新是一个例外,只要一个批量的大小保持在合理范围内,还是有好处的,但是要记住不要任何时候都盲目使用批量。 10、在Red Hat企业版(RHEL)中,节点无法加入到集群中。 查看SELinux是否开启了,把它关掉。 11、我怎么取消订阅apache cassandra邮件列表 发邮件到user-unsubscribe@cassandra.apache.org 12、为什么使用top命令看到cassandra使用了比java虚拟机限制的对内存还要多的内存? cassandra内部使用内存映射文件(mmap). 也就是锁,我们使用操作系统的虚拟内存系统把一定数量的磁盘文件映射到了cassandra进程的地址空间里。这将使用虚拟内存,也就是地址空间,这可以使用一些工具例如top命令发现,不过在64位操作系统中,虚拟地址空间是无限大的,所以你不需要担心这些。 那使用的内存的所代表的意义是什么呢?它是使用brc()或者mmap所实际占用的内存,问题的关键是,对于mmap的文件不一定会永久驻留在内存里。所以这些使用的内存不过是缓存而已,就像系统的IO会使用内核的page缓存一样。 一般的IO和mmap的差别就在于mmap引擎的内存是映射到某个进程上的,所以你用top命令可以看到该进程对应的虚拟内存大小。mmap比IO的一个好处是只要内存里有,你里面就能读到了,不会碰到page fault(读系统page缓存,内核可能需要做semi-context切换?),更多细节参考http://www.varnish-cache.org/trac/wiki/ArchitectNotes 13、种子节点是什么? 种子节点用于节点启动的时候发现整个集群。 如果你配置了你的节点指向几个节点作为种子,那么你集群中的节点会发送相比非种子节点较多的gossip信息到种子节点。换句话说:种子节点相当于gossip网络的集线器,每个节点通过种子节点可以很快知道其他节点的状态。 在一个节点新加入集群的时候,需要指定种子节点用于发现集群中其它节点,当你增加一个新节点到集群中的时候,你需要至少指定一个活着的种子节点可以连接,一旦一个节点加入这个集群,它学习到了其它节点,他在下次启动的时候就不需要种子节点了。 你可以任何时候设置任何一个节点为种子, 对于种子节点没有什么特殊的,只要你把它写入种子列表里,他就是一个种子节点。 种子是无法自启动的(bootstrap)(因为如果一个节点把自己加入了种子列表,那就是说他需要自己传输数据给自己),如果你需要这样,你可以先把这个节点当非种子节点启动,等启动以后再把它加入种子列表里。当然如果你是初始化一个新集群,没有任何数据,那你就不需要担心这个事情了。 提醒以下两点: 为每个Data center都选择大于两个节点作为种子节点 保持你所有节点种子列表是一样的。

2017年2月19日 · 1 分钟

[翻译]Cassandra经常被问到的问题(一)

1、为什么不可以设置listen_address为0.0.0.0(意思是监听所有地址)? Cassandra是一个基于gossip协议的分布式系统,监听地址是用来告诉其它节点来访问的,告诉别的节点说“连接我任何地址都可以”,是一个糟糕的想法,如果集群中不同的节点使用了不同方式的地址,悲剧的事情就要发生了。 如果你不想为你集群中的每个节点单独配置ip(非常可以理解),你可以不配,空着它,Cassandra将会使用InetAddress.getLocalHost()来选择地址,然后只要你或者你的运维团队保证这个是正确的(/etc/hosts/,dns 等等要配置对)。 一个例外是JMX,他默认监听的地址是0.0.0.0(这个是java的bug 6425769) 请看CASSANDRA-256 和 CASSANDRA-43获取这方面更多的细节。 2、cassandra用了哪些端口? 默认Cassandra使用7000作为集群通信端口(如果开启了SSL就是7001端口)。9042端口用于native协议的客户端连接。7199端口用于JMX,9160端口用于废弃的Thrift接口。内部节点通信以及native协议的端口在cassandra配置文件里可以配置。JMX端口可以在cassandra-env.sh配置(通过JVM的参数)。所有端口都是TCP的。 3、当往集群中增加新节点的时候,对于存在的数据发生了什么? 当一个新节点加入到集群,它将会自动连接集群中的其它节点,并且去复制正确的数据到本地,同样的增加、替换、移动、删除节点都是这样的。 4、我删除了数据,但是磁盘使用率没有变化,这是为什么? 写入到cassandra里的数据会被持久化到SSTable文件里,SSTable文件是不可改变的,也就是说当你执行删除的时候,数据不会从文件中被去除掉的。相反,一个标记(也叫tombstone)会被写入用于标记对应记录的新状态。不用担心,当数据和tombstone发生第一次compaction的时候,数据会被删除掉,相应的磁盘空间也被回收,你可以了解关于Compaction的更多细节。 5、为什么用nodetool ring只能看到一条记录? 即便所有节点输出的日志里可以看出,他们都发现彼此加入到了这个ring。 这个发生于你的所有节点都配了通用的token,不要这么做。 这经常发生于哪些使用VM部署cassandra的用户,(特别是使用Debian package,它会在安装完自动启动cassandra,所以会生成token并保存它。),安装好后就把VM整个克隆出另外的节点。 增很容易修复,只要把数据目录以及commitlog目录删除,然后保证每个节点是随机生成的token,再启动就可以了。 6、我可以修改一个正在运行中的集群中的keyspace的副本因子吗? 可以,但是修改后需要执行repair或者cleanup来改变已存数据的副本个数。 首先使用cqlsh修改目标keyspace的副本因子。 如果你是减少副本因子,你可以执行nodetool cleanup去删除多余的副本数据,对每个节点都要执行。 如果你是增加副本因子,你需要执行nodetool repair来保证数据的副本个数满足当前的配置。 Repair只要对每个副本集执行一次即可。这是个敏感的操作,这会影响集群的性能。强烈建议执行rolling repair,因为试图一次修复整个集群的话,那可能是个坑。 7 可以使用cassandra存储大的二进制字段吗? Cassandra并没有对存储大文件或者二进制,以及这样一个二进制数据被经常读,也就是整个发送到客户端的情况进行优化。因为存储小的二进制数据(小于1MB)应该不是问题。但是还是建议把大的二进制数据分隔成小块。 需要特别注意的是,任何大于16MB的值,将被Cassandra拒绝掉,这是由max_mutation_size_in_kb配置项决定的(这个配置项默认是commitlog_segment_size_in_mb的一半,commitlog_segment_size_in_mb默认是32M)。 8、Nodetool连接远程服务器的时候,提示“Connection refused to host: 127.0.1.1” ,这是为什么? nodetool依赖JMX,JMX依赖RMI。RMI在两端通信的时候会根据需要创建自己的listenners和connectors。通常,这些都是底层透明的,但是不正确的hostname解析,无论是在连接方还是被连接方,都会导致错乱和这样的拒绝异常。 如果你在使用DNS。确保两端机器的/etc/hosts文件是正确的。如果还是失败的,你可以尝试通过jvm选项-Djava.rmi.server.hostname=指定你要连接的远程机器名称给JMX接口,配置项大体在cassandra-env.sh文件的靠下的位置。

2016年12月3日 · 1 分钟

[新闻] 华为9月1日在IFA2016将发布新品

余承东官方微博: 表示9月1日IFA2016电子展期间,有新机要发布,发布会的时间为北京时间9月1日16点30分。 然而,一直没有透露具体手机型号的信息。随着华为手机产品线总裁何刚否认新品是华为Mate 9/S系列之后,全新系列Nova的消息也越来越多,预计将在发布会上再进行推出。不过,近日来余承东又再一次主动爆料,暗示发布会上新品不止一款。 在微博中,余承东连续晒出了多张海报图,而每次都会有两款手机现身,摄像头部分可以明显看出不同,并且四张海报都不一样!

2016年8月31日 · 1 分钟

[新闻] 荣耀8, 美得与众不同

7月11日,荣耀年度旗舰新品荣耀8,在上海东方体育中心盛大发布。在拥有旗舰性能的同时,荣耀8在外观ID设计上大胆创新,以全新设计理念和制造工艺,诠释出“美得与众不同”的产品主张。今年人气超女王金金出席现场,并激情献唱高晓松专为荣耀所做的主题曲《荣耀》,引发现场合唱,将气氛推至高潮。 在一体化的设计理念下,荣耀8不仅延续了荣耀年度旗舰的极致科技、领先配置和强劲性能,更融入了荣耀对潮流的理解,并革命性地赋予其极致美学。 作为荣耀首款采用双面2.5D玻璃设计的机型,荣耀8在颜值、手感、拍照、续航、性能方面全面进化 : 为了追求更高的颜值,除采用亮屏0.4mm超窄可视边框和全新镜面屏幕边框设计外,荣耀8更带来工艺的突破,通过15层工艺技术,打造出蕴繁于简的视觉美学。荣耀8的背部玻璃后壳油墨丝印层、多层光学镀膜、3D光刻层、光栅纹理载体层、AR光学增透层、2.5D第三代大猩猩玻璃和AF指纹易擦拭涂层等15层工艺匠心打造,创新性的技术,更高的工艺,最终为消费者带来了炫美的极光效果;而5.2英寸LTPS屏幕的运用,对称美学理念,完美均衡了屏幕的观感和整机手感。 配置方面,一体化纯平设计的黑白+彩色双1200万像素平行镜头;配备16纳米的麒麟950芯片和4GB四通道内存超强组合,以及内置的i5智能协处理器,对手机内的传感器进行精准高效的管理,同时可有效降低整机功耗;4G+网络、VoLTE高清通话,以及智能手机行业首次运用的WLAN+3.0技术,带来更任性的网络体验;3000mAh高密度电池配合领先快充技术,同时支持新一代智电技术;在UI方面,搭载基于Android 6.0操作系统的EMUI 4.1。 此外,荣耀8还拥有多项黑科技,如智灵与指纹二合一的多功能指纹键、国家眼科工程中心技术指导的护眼模式、安全便捷的移动支付功能,以及引领智控再次革新的智能4.0红外遥控技术等,全面进化带来更优秀的用户体验。 全新荣耀年度旗舰荣耀8包括4个版本,满足消费者的不同需求。其中,4G+64G全网通版售价2499元,4G+32G全网通版售价2299元,3G+32G全网通版售价1999元,3G+32G运营版售价1999元。在备受年轻消费者关注的颜色方面,荣耀8有流光金、幻夜黑、珠光白、魅海蓝、樱语粉共5种颜色,结合独特背部玻璃极光,带给消费者差异化的炫酷潮流体验。 同时,此次发布会除发布荣耀8这款“美得与众不同”的全新旗舰产品外,还发布了另外一款“与众不同”的产品——荣耀畅玩手环A1 SS版,并将在天猫旗舰店和华为商城于7月11日到18日预售, 在7月19日正式开售。 除发布全新旗舰产品外,此次发布会的一大亮点是,正式宣布吴亦凡成为荣耀品牌中国区代言人。吴亦凡是当下最具影响力的潮流偶像,在成为娱乐圈票房保证的同时,更以自己在体育、时尚等领域的超凡表现,成为最受年轻人喜爱的、时下炙手可热的多栖明星。选择吴亦凡代言,是荣耀与年轻消费者互动的重要营销举措,也是荣耀8“美得与众不同”产品主张的最佳呈现。此外,荣耀8的国际化形象和全球化的销售预期与吴亦凡的全球化形象高度重合。毫无疑问的是,吴亦凡的助阵将让本就惊艳的荣耀8如虎添翼,让科技美学旗舰开启一股青春风暴。

2016年7月13日 · 1 分钟