Janus的使用过程中, 在数据量超过百亿级别之后, 会有很多奇奇怪怪的问题, 特别是由于它后端依赖Cassandra/Hbase +ES. 导致各种组件都可能出现问题, 线上环境排查需要一个快速定位的渠道. 这里是我自己的一些血泪总结. (顺便也是告诫大家, 数据量超过百亿, 还是别考虑使用Janus了, 无数的坑而且很难排查…)
补充: 如果要使用Janus, 尽量使用最新版本的Cassandra/ES (Hbase2.0 以内别考虑使用…)
今天就先来看看传统图算法里, 使用频率最高之一的K-neighbor (K步邻居)算法的实现源码, 从而分析如果要提高查询速度, 还能从哪些方面入手优化.
0x00. 整体环境
首先确定版本,因为不同版本可能导致错误, 详情适配参考官方github的release页面,
| 服务 |
版本 |
备注 |
| JanusGraph |
0.1.1 ~ 0.3.x |
官方版+自己开发修改 |
| ElasticSearch |
1.6.0 ~ 6.x |
官方版+部分修改 |
| Cassandra |
3.0.3 ~ 3.1x |
官方版+部分修改 |
构建环境,核心就是修改配置文件.… 但是集群环境修改尽量别手动传文件然后修改,这样非常容易出错,而且多个集群启动关闭等操作也很繁琐,出错有时候不提示很难发现.(最后发现可能就是复制粘贴的时候哪个地方写错了一点…..)
补充: 集群环境下, 必须有一个批量的分发SSH命令/文件的工具, 推荐go写的开源分发, 没必要用什么ansible (慢/复杂/且功能太多根本用不到)
0x01. ElasticSearch配置和命令
须知:
在ES中,index相当于数据库,type相当于表,而mapping则相当于表结构. 简单来讲,ES会在你插入数据的时候,自动根据数据类型设置mapping格式。而且因为一般文档数据都是不规则的,所以ES的mapping会根据插入值格式的变更,自动进行mapping变更
这里需要修改vi ./root/config/elasticsearch.yml配置文件:
1 2 3 4 5 6 7 8 9 10
| discovery.zen.minimum_master_nodes: 1
discovery.zen.ping.unicast.hosts: ["10.xx.xx.xx:9300"] http.cors.allow-origin: "http://10.xx.xx.xx" index.number_of_shards: 3 index.number_of_replicas: 1
gateway.recover_after_nodes: 1
|
`使用分发工具, 批量修改ES配置文件, 并批量启动, 注意ES重启一次的时间可能会长达5分钟才能生效…. 注意盯一下 (注意不要使用 kill -9 强制结束ES进程,容易造成重分片. ) , 并建议使用各种监控工具, 监控ES的常见指标, 包括9200端口等..
下面是一些生成环境经常用得到的排查ES错误的用法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
| ps -ef | grep ` jps |grep Elastic | awk '{print $1}' `
curl localhost:9200 && curl localhost:9200/_cat/health?v
curl localhost:9200/_cat/indices?v curl localhost:9200/_cat/master?v curl localhost:9200/_cat/thread_pool?v
curl http://localhost:9200/index_name/_mapping?pretty
curl -XGET 'http://localhost:9200/_cluster/health?level=indices&pretty'
curl -XGET 'http://localhost:9200/_cluster/health?pretty'
curl -s 'localhost:9200/_cat/shards' | fgrep UNASSIGNED curl -XGET localhost:9200/_cat/shards?h=index,shard,prirep,state,unassigned.reason| grep UNASSIGNED
curl -XDELETE 'localhost:9200/index_name/'
curl localhost:9200/_cat/nodes |sort -k 1
grep reason /path/to/es/logs/xxx.xx.xx.log
curl -s 'localhost:9200/_cat/allocation?v'
curl localhost:9200 && curl localhost:9200/_cat/health?v ps -ef | grep ` jps |grep Elastic | awk '{print $1}' ` && jstat -gcutil ` jps |grep Elastic | awk '{print $1}' ` jstat -gcutil ` jps |grep Elastic | awk '{print $1}' ` | awk '{print $4}' sh ./software/es/bin/start.sh && tail -f ./software/es/root/ES0/logs/netlab.graph.lycc.log
echo never | sudo tee /sys/kernel/mm/transparent_hugepage/enabled
|
很多时候ES每个节点状态不同, 需要一个个确定, 这时候使用命令分发工具, 然后参考如下命令:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| ps -ef | grep -i ElasticSearch|grep -v grep |awk '{print $2}'
ps -ef | grep -i ElasticSearch|grep -v grep | grep Xms31g
kill ` jps |grep Elastic | awk '{print $1}' ` && jps
{ "cluster_name" : "graph-test-jin", "status" : "red", "timed_out" : false, "number_of_nodes" : 3, "number_of_data_nodes" : 3, "active_primary_shards" : 0, "active_shards" : 0, "relocating_shards" : 0, "initializing_shards" : 0, "unassigned_shards" : 0, "number_of_pending_tasks" : 0, "number_of_in_flight_fetch" : 0, "indices" : { } }
|
在线修改配置ES日志等级:
1 2 3 4
| PUT /_cluster/settings { "transient" : { "logger.discovery" : "WARN" } }
|
ES的常见操作:
1 2 3 4 5
| curl -XGET http://ip:9200/test_jin/_search?q=a
curl -XGET 'http://localhost:9200/index_name/_settings?pretty'
|
0x02. ES的特别问题处理
1. 删除无用的index文件
1 2 3 4 5 6 7 8 9
| curl localhost:9200/_cat/indices?v |egrep ".jsp|.php|.txt|.exe|.pl|.cgi" |awk '{print $3}' > delete
for i in `cat delete` ; do echo $i && curl -XDELETE 127.0.0.1:9200/$i ; done
ls /path/to/es/xxx_name/nodes/*/indices
|
2. 定时清空ES的日志
可以写个很简单的shell逻辑, 删除5天以上的ES日志, 因为ES的日志增长速度实在是太快了…
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| #!/bin/bash path="/path/to/elasticsearch/logs/"
find $path -mtime +5 -name "*.log*" -exec rm -f {} \; if [ $? == 0 ] then du -sh $path echo "del succeed,check storage" else echo "Failed!check path" fi
|
最后通过批量添加0 0 * * 0 cd /home/graph && sh delLogs.sh > /dev/null 2>&1 到每台机器的crontab文件即可, 权限不足就用crontab file 的方式写入.
0x03. Cassandra配置
首先修改在 ./conf/cassandra.yml 的两个配置
- cluster-name (注意如果不是第一次修改,那么需要先
rm -rf 清空一下data存放地的文件.不然会提示和现有数据不一)
- seedAddress
./bin/cassandra &启动cassandra ,默认端口9042
然后是否需要开启thrift./bin/enablethrift 默认端口9160
健康检查:
1 2 3 4 5 6 7 8 9
| ./bin/nodetool status
-- Address Load Tokens Owns Host ID Rack UN 10.xx.xx.xx 165.95 KB 256 ? 03d47f63-..-1610a644cc36 rack1 UN 10.xx.xx.xx 171.51 KB 256 ? 2484e7a7-..-9b084fc6f85e rack1 UN 10.xx.xx.xx 177.33 KB 256 ? e42dc94f-..-52cbd8f2a586 rack1
|
0x04. Janus配置
启动好ES+csd之后再修改两个文件,就可以sh bin/gremlin-server.sh & 启动Janus和Gremlin-Server了. 注意不要直接使用自带的janus启动脚本, 可能会启动到默认内嵌的ES和Cassandra..
修改 vi conf/gremlin-server/gremlin-server.yaml 的graphs:{graph:conf/gremlin-server/xxx.properties}
找到1对应的xxx配置文件,在原本的vi conf/gremlin-server/janusgraph-xx.properties的基础上,修改以下:
1 2 3 4 5 6 7 8
| storage.hostname=xx,xx
storage.cassandra.keyspace=xxx
index.search.hostname=xx,xx index.search.index-name=xxx
|
Janus的日志只有一个, 所以盯着看吧… 注意切分一下, 默认会是一个文件越来越大, 而且日志信息里一大堆无用信息….
1 2 3 4 5
| cat xx.log | grep -C 15 exception -ni
tail -5000 /path/tojanusgraph/log/gremlin-server.log|grep -i Exception -nC 10
|
参考文章
- 处理ES各种问题汇总-En(推荐)
- es状态为红或黄
- 彻底解决es-unsigned-shards未分配切片问题
- 解决ES状态红色
- 官方文档-集群健康 11.11更新
- ES的几个问题解决(Unsigned-shards/文件数)
- github文档
- ES之Mapping相关
- ES常见19个查询语句