Cassandra是Facebook开源的一个NoSQL数据库,它除了具备一般的NoSQL分布式数据库特点以外,最大的一个特点是去中心化架构设计,这和Hadoop HDFS/HBase等不一样,比如HDFS分为NameNode和DataNode,而Cassandra集群中所有节点都是数据节点,每一个节点都在集群中承担相同的角色。

        我们开始在2013年做大数据存储系统选型过程中,也考虑过Cassandra,不过最终选择了MongoDB,之后又使用Elasticsearch,一直与Cassandra无缘,不过前几年我们引入了一款商业的AI类系统,它的后台存储系统选择了Cassandra,迫使我们不得不去熟悉Cassandra系统,然而一般是运维人员去维护它,常常也是咨询厂家运维人员来解决具体问题。

        最近由于某地市平台的运维人员休长假,由我来暂时接管其运维工作。这个系统中的Cassandra被限制只能存储2亿特征向量数据,到达这个阙值之后,系统将不永许再新增任何特征向量记录。我们每天大概几百万的采集量,大概3月左右就会存储满,所以运维人员写了一个定时清除脚本,指定一个上限阙值,一旦超过这个阙值,脚本将删除最早的一天数据,一直到存储量低于这个阙值才停止,比如阙值190000000,但是,在crontab配置时编辑错误,也没有事后进行检查,致使一直没有生效,时间到了3个月之后某一天,客户发现数据前一天没有入库,马上给我电话,他立即赶到现场,稍微分析发现Cassandra容量已经刚好达到2亿,厂家业务系统停止入库了。

        得知具体原因之后,我和主开发人员商量清理一部分数据,反正客户也不要求那么多天数据,我们的特征向量存储远比图片文件存储的时间长,所以主开发人员给我建议是先删除5000万。这个数据量也不大,我也没想那么多,使用厂家删除库接口进行删除,我们是一天一个特征向量库的,于是用Python脚本调用厂家接口从最早库进行删除,一直删除到库容量小于1.5亿,删除倒是很快完成,删除之后我第一时间用库列表查询接口去看,第一次查询还能出结果,但是再次查询的时候,接口就返回错误: no hosts availed in the pool,整个系统所有接口都不能调用了,先前还只是新增特征向量接口不行,现在什么都不行,吓了我一跳,系统这么脆弱。

        一边第一时间联系厂家远程运维人员,一边登录这台AI系统所在服务器,按厂家运维人员去看系统状态,这个系统只有一台机器,厂家却在上面安装了一个k8s单集群,本人没有使用过k8s系统,一切只能边baidu边摸索,用命令看容器状态:

        kubectl get pod -A

        发现Cassandra也是只有一个容器实例,已经是0/1了,肯定是发起删除操作的时候,让整个系统垮掉了,于是手工删除它,让k8s去重启它:

        kubectl delete pod -n component Cassandra-default-0

        但是还是启动不起来,于是强制删除:

        kubectl delete pod --force  --grace-period=0 -n compent Cassandra-default-0

        容器终于启动起来了,然后看容器日志:

        kubectl logs -f -n component Cassandra-default-0

        这时日志没有ERROR级别错误,只是大量gc1日志,看来JVM在做大量垃圾回收处理,这肯定跟删除有关了。

        再访问厂家API接口,不管是查询库列表接口、创建库接口,还是新增特征向量接口、搜索特征向量接口,都不可用,全部返回先前的错误描述:no hosts availed in the pool。

        咨询厂家运维人员,运维人员去问内部开发人员,答复是:从来没碰到一次性删除5000万数据的,删除1千万数据可能要5个小时。我说5000万数据不是要25个小时,这简直不可接受啊,但是也没办法,对方是大公司,开发人员应该是有水平,只有等了。

        但是我还是不甘心,就要自己分析Cassandra为什么会这么慢,系统内部状态是什么。于是就进入容器,直接用docker命令:

        docker ps | grep cassandra

        docker exec -it container-ID /bin/bash

        进入容器之后看进程: ps -ef | grep cassandra

        然后看端口: sudo netstat -ntlp 

        9042 : native协议服务端口

        7199  :  JMX服务端口

        这两个重要的端口都是正常存在的,于是用cqlsh工具去连接,需要密码,问厂家运维人员,回答账号在k8s环境里,于是执行:

        kubectl gett secrets password-secrets -o yaml | grep cassandra

        得到一个json格式的账号列表,Cassandra、MySQL、MinIO等登录账号都在这里,于是对密码进行Base64解码,得到密码原文。

        登录Cassandra:

   > cqlsh -u username -p password

   >> help

         所有命令都出来了,然后看键空间和表,找到特征向量所在的表,其实就一张表而已,查询都没有问题,感觉Cassandra应该已经好了啊,不至于要25个小时,再去看docker容器日志,全部是INFO和DEBUG级别日志,都是在删除sstable数据,看不出任何问题。

        我怀疑Cassandra可能已经正常,说不定是厂家自己的应用系统的问题。于是咨询厂家运维人员,他们自家开发的系统到底是怎么一个部署架构,之间是怎么调用的,我要分析一下他们的系统到底是打印什么错误。

        然后我和厂家运维从kong网关查起,发现厂家的两个程序有大量错误,错误描述还是:no hosts availed in the pool。

        我怀疑是cql连接池处理不好,于是重启厂家那两个需要连接Cassandra系统,重启之后,再去调用厂家所有API接口,一切正常。阿弥陀佛,庆幸自己没有听他们开发人员所谓的1千万数据删除要5个小时的断论,坚持了自己去分析各个系统,分析系统运行日志,整个系统提前恢复服务。

        这个过程中也怀疑过Cassandra的删除机制墓碑问题,其实不可能那么慢,5000万数据对一个NoSQL数据库应该不至于致命,但是稳定性确实有问题,单点部署情况下,删除导致单点故障而不能恢复,确实是Cassandra一个小问题,但是一般用Cassandra应该至少3个以上节点,做集群做副本集才有意义。

        

        

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐