使用maven创建自定义archetype
前言
在开发过程中经常需要新建工程,新建工程使用自带的archetype,往往不能满足项目开发需求,这就需要我们开发出自己的archetype。
实现
本次使用create-from-project来实现自定义archetype(方法至少两种)
1.构建模板项目
首先使用eclipse创建一个新的maven project,然后把配置好的一些公用的东西放到相应的目录下面 比如说会将一些常用的java代码存放到src/main/java目录下面;会将一些通用的配置文件放到src/main/resources目录下面;如果是javeEE工程,还会有一些jsp等等的文件存放到src/main/webapp目录下面
2.pom.xml编辑
在pom.xml文件中添加以下内容
1 | <build> |
3.编译
在工程跟目录下运行maven命令
1 | mvn archetype:create-from-project |
然后会在target目录下面生成generated-sources目录,这个就是生成的 archetype
4.安装/发布
进入generated-sourced/archetype目录,运行maven命令:
1 | mvn install |
这样就把自定义的archetype安装到本地仓库了。
archetype安装的地址是在maven安装目录下面的conf/settings.xml文件中指定的(
默认会在 ~/.m2 目录下面生成一个archetype-catalog.xml文件(和默认的settings.xml在同一个目录), 声明了该archetype的groupId、artifactId和其他属性。
因为Eclipse创建maven项目过程中,选择的“Default Local”指向的地址就是 ~/.m2,所以文件archetype-catalog.xml会被eclipse自动读取,使用eclipse创建maven项目的时候可以在”Default Local”一项中找到刚才自定义archetype名字。
安装到本地仓库中的archetype只可以被自己使用,如果想要共享,那么在第四步的时候使用deploy命令,不要使用install命令。
5.卸载
如果想要卸载刚才安装的archetype,只需要将~/.m2目录下面的archetype-catalog.xml文件中对应的
备注
问题:eclipse中找不到自定义archetype?
首先查看自定义的版本是否是0.0.1-SNAPSHOT,如果是这个的话,需要勾选include snapshot archetypes
参考
1.http://my.oschina.net/wangrikui/blog/498807
2.http://blog.csdn.net/sxdtzhaoxinguo/article/details/46895013
Redis Cluster慢查询修复总结
RedisCluster集群定位
故障排除
如果在产线中Redis 操作变慢,可按以下操作排除故障
- slowlog查看引发延迟的慢命令
获取10条慢操作日志
1 | slowlog get 10 |
结果为查询ID、发生时间、运行时长和原命令。默认10毫秒,默认只保留最后的128条。单线程的模型下,一个请求占掉10毫秒是件大事情,注意设置和显示的单位为微秒,注意这个时间是不包含网络延迟的。
- 监控客户端的连接
在Redis-cli工具中输入info clients可以查看到当前实例的所有客户端连接信息,过多的连接数也会影响redis性能
1 | info clients |
- 机器固有延迟
如果使用的是虚拟机的话,会存在一个固有延迟.可以使用如下命令,在redis server中执行:
1 | ./redis-cli --intrinsic-latency 100 |
100位一秒内测试数量
- 计算延迟
如果你正在经历redis 延迟问题,可能需要衡量延迟到底是多大,用以下命令即可实现
1 | redis-cli --latency -h `host` -p `port` |
- AOF和磁盘IO引起延迟
查看redis中fdatasync(2),追踪进程
1 | sudo strace -p $(pidof redis-server) -T -e trace=fdatasync,write |
- 过期key引起延迟
当数据库有超过1/4key在同一时间过期,会引起redis 阻塞
产线调整
- aof配置调整
经过查看redis log,我们发现aof延迟比较厉害,猜测写aof影响了redis 性能。但为了保证数据安全,又无法关闭aof文件。经过查看官方文档,未更改aof保存策略维持fsync every second,更改
1 | no-appendfsync-on-rewrite yes |
这个配置是指在重写aof时,不持久化数据到aof中。
- rdb配置调整
线上机器IO操作特别频繁,用命令
1 | iostat -d -k 2 |
查看当前IO情况。经过查看发现redis rdb temp文件变更比较频繁。将配置改为
1 | save 600 30000 |
线上机器IO才降下来。
Client使用定位
- pipeline操作串行改并行
经过测试,高并发情况下,key批量pipeline处理已经成为性能瓶颈。经过分析将这块的处理更改成并行处理,并行处理的线程数为当前master的数量,这样会将Client的处理能力提升n倍,经过测试,效果明显。
- 集群节点信息单独线程维护
之前Client为了实时获取集群node信息,在每次操作都会主动获取集群信息。这里操作不用这么频繁,如果并发特别大的话,也会消耗大量的时间,经过分析后将此处做更改。有两种修改方法(1.)单独新建线程,专门维护集群信息(2.)更改成处理失败情况下,再去更新集群信息。目前采用第二种
- 增加slow log记录
系统如果不存在对操作时间log统计,那么就会出现不容易定位是哪一块出的问题,但也是一把双刃剑,增加slow log 统计会浪费时间,增加系统负担。基于以上综合考虑:特将slow log架构设计成通过rest API动态改变统计维度,统计分为set和get两种(set数据理论上会比get数据慢)。
问题1
更改成并行处理后,出现许多莫名其妙的问题,错误如下:
1 | redis.clients.jedis.exceptions.JedisConnectionException: Unexpected end of stream. |
解决
分析log,发现有同时多线程处理同一个key情况,更改key处理顺序,避免多线程同时操作一个key,此问题再未复现。
问题2
更改成并行处理后,出现开始一部分操作报null错误
解决
分析log,发现多线程同时调用一个获取集群信息方法,该方法避免多次调用,已经加lock,这会导致多数线程得不到集群信息,因此会出现null,将该方法提到初始化时即调用,彻底避免多线程调用。
参考
以下链接为我收藏的网址,对追踪Redis latency有很大帮助
Java 多线程实现方式
Java 多线程实现方式
新建线程
1.继承Thread,复写run
实现一个线程最简单的方法
1 | new Thread() { |
2.实现runnable,实现run
runnable是一个接口类,使用的话,需要实现。
1 | new Thread(new Runnable() { |
3.利用jdk中Executor框架实现
Executors类,提供了一系列工厂方法用于创先线程池,返回的线程池都实现了ExecutorService接口。其中包括线程池,Executor,Executors,ExecutorService,CompletionService,Future,Callable等。
1 | ExecutorService executorService = Executors.newSingleThreadExecutor(); |
带返回值的多线程
结合Future,Callable一起使用,可以取得多线程执行的返回值
1.第一种
1 | ExecutorService executorService = Executors.newFixedThreadPool(10); |
2.第二种
1 | ExecutorService executorService = Executors.newFixedThreadPool(10); |
利用外部表读取orc文件
利用外部表读取orc文件
前言
因为orc文件压缩,并且可以快速加载到hive中,因为这种应用于hadoop平台的上文件获得许多开发者的注意。
ORC : Optimized Row Columnar (ORC) file
据官方文档介绍,这种文件格式可以提供一种高效的方法来存储Hive数据。它的设计目标是来克服Hive其他格式的缺陷。运用ORC File可以提高Hive的读、写以及处理数据的性能。
方案
可以利用构建hive中外部表来读取orc文件。
1.建表
其中location即为orc文件所在的目录,该目录下新增的文件,都可以被hive查出
1 | CREATE EXTERNAL TABLE test_orc_v2( |
2.orc文件生成
1 | import java.io.IOException; |
其中OrcUtils使用如下依赖,在pom中注意添加
1 | <dependency> |
Redis Cluster Resharding
Redis Cluster Resharding实践
简介
在Redis Cluster运维过程中,会出现水平扩展集群,而水平扩展集群即新增master节点。Redis Cluster需要就需要重新划分slot,数据迁移等操作,本文只是探讨实现过程,用Redis-cli自带命令实现Resharding。
实践
过程简介
真正开始Resharding之前,会先在源结点和目的结点上执行cluster setslot
关于迁移过程中的数据访问,客户端访问源结点时,如果Key还在源结点上就直接操作。如果已经不在源结点了,就向客户端返回一个ASK错误,将客户端重定向到目的结点。
实践过程
1.redis-cli 实现
迁移备注:
实现迁移9013node中952 slot到9015 node上,其中源9013 node_id为a92e4554aa2828b85f50f8f8318429d68f5213ca,目的9015node_id为c725cda7b314701c6892f035224700e9a8336699
- 详解
1
2
3
4
5
6在迁移目的节点执行cluster setslot <slot> IMPORTING <node ID>命令,指明需要迁移的slot和迁移源节点。
在迁移源节点执行cluster setslot <slot> MIGRATING <node ID>命令,指明需要迁移的slot和迁移目的节点。
在迁移源节点执行cluster getkeysinslot获取该slot的key列表。
在迁移源节点执行对每个key执行migrate命令,该命令会同步把该key迁移到目的节点。
在迁移源节点反复执行cluster getkeysinslot命令,直到该slot的列表为空。
在迁移源节点或者目的节点执行cluster setslot <slot> NODE <node ID>,完成迁移操作。 - 实践相关命令参考如下:
1
2
3
4redis-cli -c -p 9015 cluster setslot 952 importing a92e4554aa2828b85f50f8f8318429d68f5213ca//目的节点执行
redis-cli -c -p 9013 cluster setslot 952 migrating c725cda7b314701c6892f035224700e9a8336699//源节点执行
redis-cli -c -h 192.168.0.101 -p 9013 migrate 192.168.0.101 9015 "truman:00000829" 0 1000
redis-cli -c -p 9015 cluster setslot 952 node c725cda7b314701c6892f035224700e9a83366991
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20//集群
CLUSTER INFO 打印集群的信息
CLUSTER NODES 列出集群当前已知的所有节点(node),以及这些节点的相关信息。
//节点
CLUSTER MEET <ip> <port> 将 ip 和 port 所指定的节点添加到集群当中,让它成为集群的一份子。
CLUSTER FORGET <node_id> 从集群中移除 node_id 指定的节点。
CLUSTER REPLICATE <node_id> 将当前节点设置为 node_id 指定的节点的从节点。
CLUSTER SAVECONFIG 将节点的配置文件保存到硬盘里面。
//槽(slot)
CLUSTER ADDSLOTS <slot> [slot ...] 将一个或多个槽(slot)指派(assign)给当前节点。
CLUSTER DELSLOTS <slot> [slot ...] 移除一个或多个槽对当前节点的指派。
CLUSTER FLUSHSLOTS 移除指派给当前节点的所有槽,让当前节点变成一个没有指派任何槽的节点。
CLUSTER SETSLOT <slot> NODE <node_id> 将槽 slot 指派给 node_id 指定的节点,如果槽已经指派给另一个节点,那么先让另一个节点删除该槽>,然后再进行指派。
CLUSTER SETSLOT <slot> MIGRATING <node_id> 将本节点的槽 slot 迁移到 node_id 指定的节点中。
CLUSTER SETSLOT <slot> IMPORTING <node_id> 从 node_id 指定的节点中导入槽 slot 到本节点。
CLUSTER SETSLOT <slot> STABLE 取消对槽 slot 的导入(import)或者迁移(migrate)。
//键
CLUSTER KEYSLOT <key> 计算键 key 应该被放置在哪个槽上。
CLUSTER COUNTKEYSINSLOT <slot> 返回槽 slot 目前包含的键值对数量。
CLUSTER GETKEYSINSLOT <slot> <count> 返回 count 个 slot 槽中的键。
2.redis-trib.rb 实现
1 | #把127.0.0.1:9013当前master迁移到127.0.0.1:9015上 |
参考
linux运维问题
linux 运维
1.后台执行任务
问题描述:
在linux中执行一些服务,我们通常会使用sudo命令,以root权限运行,再以nohup后台运行,但是有的情况下需要交互操作。
解决方案:
1.首先输入命令,
1 | sudo nohup commandline |
2.使用以下快捷键中断
1 | ctrl+z |
3.在命令台中输入
1 | bg |
2.监控linux磁盘IO
可以使用iostat命令,iostat还有一个比较常用的选项-x,该选项将用于显示和io相关的扩展数据。(可以结合grep一起使用便于过滤具体磁盘)
命令解释:
参数 -d 表示,显示设备(磁盘)使用状态;-k某些使用block为单位的列强制使用Kilobytes为单位(同样可以用m表示兆);2表示,数据显示每隔2秒刷新一次。
1 | iostat -d -k 2 |
输出信息解释
1 | tps:该设备每秒的传输次数(Indicate the number of transfers per second that were issued to the device.)。"一次传输"意思是"一次I/O请求"。多个逻辑请求可能会被合并为"一次I/O请求"。"一次传输"请求的大小是未知的。 |
ES+Kibana+Packetbeat使用总结
简介
ElasticSearch是一个基于Lucene的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎。Kibanna是针对ElasticSearch一个界面UI。Packetbeat是监控网络数据包一个工具,分布式wireshark。
Packetbeat 是一个实时的网络数据包分析器,通过结合ES可以构建一个应用监控和性能分析系统。Packetbeat 可以将监控数据发送到es,或者redis,logstash中。目前支持以下协议:
- ICMP (v4 and v6)
- DNS
- HTTP
- Mysql
- PostgreSQL
- Redis
- Thrift-RPC
- MongoDB
- Memcache
搭建
搭建Es
- 下载
1
wget https://download.elastic.co/elasticsearch/release/org/elasticsearch/distribution/tar/elasticsearch/2.3.4/elasticsearch-2.3.4.tar.gz
- 解压
1
tar -xvf elasticsearch-2.3.4.tar.gz
- 配置 ES
默认配置即可正常使用,但配置config/elasticsearch.yml使用效果更好。
配置如下: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
32cluster.name: my-application
node.name: node-1
node.master: true
node.data: true
path.logs: /data/truman/elasticsearch-2.3.4/logs
bootstrap.mlockall: true
network.host: 192.168.1.42
http.port: 9200
discovery.zen.ping.multicast.enabled: false
discovery.zen.ping.unicast.hosts: ["192.168.1.42"]
discovery.zen.fd.ping_interval: 1s
discovery.zen.fd.ping_timeout: 30s
discovery.zen.fd.ping_retries: 5
action.auto_create_index: true
action.disable_delete_all_indices: true
indices.memory.index_buffer_size: 30%
indices.memory.min_shard_index_buffer_size: 12mb
indices.memory.min_index_buffer_size: 96mb
action.write_consistency: one
index.number_of_shards: 3
index.number_of_replicas: 1
threadpool:
bulk:
type: fixed
queue_size: 300
index.translog.flush_threshold_period: 10m - 启动
在使用root账户启动脚本可能会报错,在次修改一下elasticsearch启动脚本,增加以下内容:然后后台启动脚本1
ES_JAVA_OPTS="-Des.insecure.allow.root=true"
访问 http://192.168.1.42:9200/即可查看是否启动成功。1
nohup bin/elasticsearch &
- 安装head plugin
head 插件能够可视化操作index与数据,在http://192.168.1.42:9200/_plugin/head/上进行操作
安装
1 | bin/plugin install mobz/elasticsearch-head |
移除
1 | bin/plugin remove head |
安装kibana
- 下载
1
wget https://download.elastic.co/kibana/kibana/kibana-4.5.2-linux-x64.tar.gz
- 启动在浏览器中访问http://192.168.1.42:5601查看是否成功。
1
2
3tar -xvf kibana-4.5.2-linux-x64.tar.gz
cd kibana-4.5.2-linux-x64
bin/kibana
安装Packetbeat
- 下载
1
wget https://download.elastic.co/beats/packetbeat/packetbeat-1.2.3-x86_64.tar.gz
- 解压
1
tar -xvf packetbeat-1.2.3-x86_64.tar.gz
- 配置 Packetbeat
修改es输出即可,默认是localhost,将该内容修改为es所在的主机ip,即可使用默认配置运行了。修改完成后,可以通过以下命令检验修改配置是否正确(该shell需要root权限)1
2
3
4
5
6
7
8
9
10
11
12
13
14
15output:
### Elasticsearch as output
elasticsearch:
# Array of hosts to connect to.
hosts: ["192.168.1.42:9200"]
template:
# Template name. By default the template name is packetbeat.
#name: "packetbeat"
# Path to template file
path: "packetbeat.template.json"
# Overwrite existing template
#overwrite: false1
sudo ./packetbeat -configtest -e
- 加载索引模板(index template)到es
- 加载加载成功后,访问以下网址,看packetbeat索引模板是否加上。
1
curl -XPUT 'http://192.168.1.42:9200/_template/packetbeat' -d@/etc/packetbeat/packetbeat.template.json
1
http://192.168.1.42:9200/_template/packetbeat
- 删除模板文件
1
curl -XDELETE 'http://192.168.1.42:9200/_template/packetbeat'
- 启动
1
sudo nohup ./packetbeat &
- 测试
模拟简单http请求查询数据1
curl http://www.aibibang.com > /dev/null
查询出数据,即可证明安装成功!1
curl -XGET 'http://192.168.1.42:9200/packetbeat-*/_search?pretty'
经验总结
- 索引未创建成功
在搭建过程中,可能由于索引模板配置错误,导致索引未创建成功。但还存在一种情况,即没有数据采集进去。采集到数据以后才会根据索引模板创建索引
2. thrift 监控配置
目前对thrift监控仅支持binary协议,详细配置如下
1 | thrift: |
- 修改采集字段
使用过程中,希望采集自定义字段,当前版本未发现。但在最新版本5.0.0-alpha4中可通过修改yml配置文件删除掉不需要采集的字段。
在5.0.0-alpha4中配置如下:其实老的版本在index template中也是可以设置的。通过设置_source,例如:1
2
3filters:
- drop_fields:
fields: ["request", "query","server","proc","client_server"]1
2
3
4
5
6
7
8
9
10
11"_source": {
"excludes": [
"request",
"query",
"server",
"proc",
"params",
"beat.hostname",
"client_server"
]
},
RedisCluster搭建
RedisCluster搭建
前言
现在越来越多的公司开始使用redis cluster,这就要求大家能够学会快速搭建redis cluster集群,在官网上也是有很详细的入门指导,本文章只是自己搭建后总结,主要使用两种方式搭建:1. 官网上使用的redis-trib.rb脚本构建集群;2. 使用shel 命令搭建。
准备
因为两种方式都需要提前启动好相应的redis实例,因为将公共步骤放在准备工作中。这一步比较简单,主要是按端口新建不同文件夹,然后复制redis.conf,修改其中port对应的端口。集群高可用需要至少三个node,本次采用3 master、3slave架构。步骤如下:
1.
1 | mkdir 9000 |
修改复制后的redis.conf:
cluster-enabled yes
port 90001
src/redis-server 9000/redis.conf
然后重复以上操作 9001-9005
rb脚本创建
准备操作中已经建立了6个独立的node,接下来执行以下脚本:
1 | /src/redis-trib.rb create --replicas 1 127.0.0.1:9000 127.0.0.1:9001 127.0.0.1:9002 127.0.0.1:9003 127.0.0.1:9004 127.0.0.1:9005 |
在执行脚本后,确认自动计算的分配方案,即可搭建好redis cluster集群
shell创建
1.集群meet
1 | src/redis-cli -p 9000 cluster meet 127.0.0.1 9001 |
2.划分master,slave
1 | src/redis-cli -c -h 127.0.0.1 -p 9001 cluster nodes |
根绝ID指定为哪个node的slave
1 | src/redis-cli -c -h 127.0.0.1 -p 9003 cluster replicate 5ba760249e5dfc478f5066a98922e0f3268075fd |
3.分配slot
因为cluster addslots命令不支持区间分配slot,因此只能借助shell实现分配slot
redis.sh如下:
1 | #/bin/sh |
执行shell
1 | ./redis.sh addslots 9000 0 5460 |
至此redis cluster 搭建完毕!
开源项目学习记录
开源项目学习记录
- Twemproxy
-简介:应用于redis代理服务,做客户端与服务端实例代理,数据自动分片,在redis cluster不成熟前被业界大量使用。
-地址:https://github.com/twitter/twemproxy - divlote collector
-简介:用来收集web用户点击行为数据,并将数据发送到kafka,hadoop中,高效简单便捷。
-地址:http://divolte.io/ - cachecloud
-简介: CacheCloud提供一个Redis云管理平台:实现多种类型(Redis Standalone、Redis Sentinel、Redis Cluster)自动部署、解决Redis实例碎片化现象、提供完善统计、监控、运维功能、减少运维成本和误操作,提高机器的利用率,提供灵活的伸缩性,提供方便的接入客户端。
-地址:https://github.com/sohutv/cachecloud - ElasticSearch+Kibanna+Packetbeat
-简介:ElasticSearch是一个基于Lucene的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎。Kibanna是针对ElasticSearch一个界面UI。Packetbeat是监控网络数据包一个工具,分布式wireshar。
-地址:https://www.elastic.co/downloads/beats