
1 将数据存储到Cassandra数据库中。
2 Cassandra是一个分布式的NoSQL数据库,数据以键值对的形式存储在多个节点上。
数据输入是指将数据写入Cassandra的节点中,以便后续进行查询和分析。
3 数据输入可以通过Cassandra提供的API、命令行工具或第三方工具(如DataStax Studio)进行。
同时,Cassandra还支持数据批量导入,以提高数据输入的效率。
12月10日下午2点,服务突然无响应,业务线接口出现大量超时,经过定位分析,发现是Cassandra查询请求大量阻塞,进一步观察日志发现是Cassandra多分区查询引起的, 虽然这个问题是由业务线的一个小bug引起的(一个in查询包含2w个元素),但同时也暴露出了我们底层服务的瓶颈问题
我们假设id是users表中的分区主键,存储了id为1、2、3、4的4条数据,极端情况下,4条数据会被分配到4个分区进行存储(但也可能在1个分区里),我们假设数据不在一个分区内,然后通过下面的语句一次查询出这4个用户的方式就是多分区查询。
假设order表中有uid, day ,productid三个字段,uid为分区键,day为排序键;我们通过下面SQL在订单表查询出用户1在某几日的消费详情,虽然这里也用到了in *** 作,但因为指定了uid为1,所以查询请求会只命中一个分区。
假设将A,B,C三条数据存储在一个9节点3副本的集群里,当我们使用SELECT FROM mykeyspacemytable WHERE id IN (‘A’,’B’,C’)这样一个查询时,Cassandra的处理机制是这样的:
客户端与服务端建立同步请求,服务端会根据平衡策略在9台节点中选择一个节点作为调制协调器,负责解析SQL并将请求转发到其它节点,然后拉取对应数据到协调器节点,协调器存储了查询关系和每个数据节点返回的数据,正常情况下当协调器节点获取所有数据后会返回到客户端,相应的如果协调器发生故障,整个查询将根据配置的重试略重新开始请求。
一版情况下多分查询是不会有任何问题的,Cassandra都能够很快的将结果进行返回,但随着业务的变动和数据增长,一次需要查询的分区主键元素会变多,相应的Cassandra需要检索的分区数量也会变大,这样会消耗更多的堆空间,并引发频繁GC导致集群可用性下降。
主要优化方式是将上面请求改为固定分区异步并发请求,上面的SQL为改成下面这种方式多次请求服务端
看到反人类的 *** 作 着实让我震惊了一把,这么做不应该更慢吗?看似不合理的 *** 作实则内有玄机。
首先,客户端会与服务端建立session会话,每个session会根据服务器情况设置对应数量的连接池,每个连接池会与服务器建立若干连接,每个连接都是异步的(采用netty异步双工技术实现),所以一个连接是可以同时发出多个请求的,在发送下一个请求前不需要等待上一个请求的完成
这种查询还有另一个好处 它不存单一的协调器节点了,查询分摊到了多个cassandra节点上,充分利用了集群的CPU和内存资源
4x
客户端提供了丰富的配置及优化策略 如失败重试策略等。篇幅有限这里就不一一列举了
多分区数据查询是比较消耗性能的,类似的还有allow filtering无法查询,如果需要一次查询的分区键元素数量不是很多,固定分区遍历查询与In关键字查询性能区别不是很大,在我们当前业务环境中通过测试发现,当一次查询元素个数超过1000时固定分区查询性能提升2倍,3000-5000时性能提升3-5倍,待查询的元素个数越多性能提升越明显,整体来看有3-10倍的性能提升,但响应时间也会相应变长。
首先,Cassandra是一个分布式数据库系统,其重置通常意味着重置所有节点的数据。因此,在考虑重置Cassandra之前,请务必备份所有的数据。如果你已经备份了数据,那么可以使用以下步骤重新启动Cassandra:首先,停止所有Cassandra节点。然后,通过替换数据目录中的所有文件来删除现有数据。接下来,重新启动Cassandra节点并创建一个新的本地密钥库。最后,将之前的备份数据加载回新的Cassandra键空间中。这些步骤应该可以恢复在Cassandra中出现的问题,并将数据还原到以前的状态。
在对某个表做count时出现如下错误(在做业务性测试,生产环境请不要简单粗暴做count *** 作,耗时还可能不准)
很奇怪,另外一个表应该是跟他相同条数的,都能直接count出来,但是当前表count一直报错,而且数据还差2两条(跟ES里面的数据对比后得知)
在网上可以直接查询相关问题,结果也出来了很多。其中我给出几个具有参考性的链接
其中第一个链接其实已经反映了我这次的问题,但是我第一眼看到这个答案并没有感觉到确切符合我当前的问题,然后后面看到第二个链接时,明白了去哪儿看日志。
在 cassandra systemlog 看到了count产生的日志,前面后后观察了很长的日志,结果会出现如下一些情况
上面是3个有不同于常见日志的信息,下面是常见的日志信息
这个问题曾经以为被定位到问题,但是最终却发现还是无能为力。这里说下历程
第一次以为找到缘由
做count *** 作 *** 作时,就跟其他读 *** 作一样,需要将数据加载到缓存中。数据来源包括 SSTables,tombstone标记,这些数据都放在缓存中。
缓存的大小由cassandrayaml中的 file_cache_size_in_mb 设置控制。 默认大小为 512 MB
count出问题这张表是因为有一个字段存了很长的文本内容,count整个表时,将所有数据(完整的每行数据)加载到内存就导致内存不足。
第二次
根据上面的方式解决count超时不久后又发现超时,但这次却是不同之前说的两个表。这次没有再去调配置大小,而是在@玄陵 的指导下 跟踪了cpu idle 跟磁盘的 %util
在跟踪的过程中刚好出现 %util 达到 100% , 99% 的情况。然后他认为就是磁盘性能造成的超时。但是我跟踪了磁盘负载很高的时间刚好是定时任务在往cassandra里面写数据。那 %util 高应该是写入造成的,我在定时任务跑完然后再去执行count 也还是超时,所以我不太认同时磁盘性能造成count超时。当然,我们的确实存在磁盘性能,这个后续需要好好调优
无果
我之前执行count sql 时一直在 datagrip (一种cassandra的可视化管理)中 *** 作。偶然想去cassandra 终端使用cqlsh执行,结果竟然有意外之喜
在cqlsh 首次执行也是超时,但是后面执行就能成功统计。而在datagrip中统计却一直出现超时错误。那这两个有什么表现不一样么
观察日志发现:在datagrip做 *** 作时,systemlog 会输出很多(全是查询的sql语句),而在cqlsh中进行统计时,发现systemlog 竟然只有少量的日志输出,甚至没有常见的查询日志,也是异常奇怪。目前找不到更多原因,只能记录存档了。
对于这个问题花费了很多力气,查过缓存不足,tombstone太多,cpu, 硬盘。但最后我更倾向这个 *** 作违反了cassandra的设计,cassandra 是分布式的,记录是分区存储。当在做 聚合查询 时 却没有带where 限制条件,那么很可能不能得到你预期的结果。count可以对一个数据量小小的table进行,但是数据量稍微大一点,可能就不能这么用了。
对于其他聚合查询请点击下面链接
解决
如果是业务层需要做count统计,需要根据分区键去做count
如果只是观察数据总条数,建议直接在cqlsh上进行统计(不要使用其他工具),当然这个也依然存在超时的问题。所以这里推荐 一个 非常好的统计工具 brianmhess/cassandra-count
这个工具通过使用numSplits参数拆分令牌范围,可以减少每个查询计数的数量并减少超时的可能性。
目前使用下来效果还非常不错
以上就是关于thingsboard用的什么持久层框架全部的内容,包括:thingsboard用的什么持久层框架、cass复合线加点的命令、cass数据输入是指等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)