Eclipse Maven Update 时JDK版本变更问题
1.新建一个Maven项目JDK版本和系统版本不对应,
2.右键Maven项目->Maven->Update ProjectJDK版本改变了,
3.操作系统的JDK重装了新的版本,这是引起前面两个现象的主要原因。
修改方法(假如系统jdk版本是1.8):
方法一:在pom.xml文件中指定jdk的版本:
1 | <build> |
1.新建一个Maven项目JDK版本和系统版本不对应,
2.右键Maven项目->Maven->Update ProjectJDK版本改变了,
3.操作系统的JDK重装了新的版本,这是引起前面两个现象的主要原因。
修改方法(假如系统jdk版本是1.8):
方法一:在pom.xml文件中指定jdk的版本:
1 | <build> |
使用案例如下:
1 | <plugin> |
在开发过程中经常需要将依赖包与代码包分离,配置文件与代码包分离,这样更便于部署与修改参数。依次案例基于以上场景展开,借助于maven-jar-plugin与maven-assembly-plugin。
pom内容如下:
1 | <build> |
package.xml内容:
1 | <assembly> |
maven-jar-plugin只是讲代码打成一个jar,而对部署包的构建是由assembly插件完成的。
结合启动、停止脚本即可高效便捷的部署一个项目。
start.sh:
1 | #!/bin/sh |
stop.sh:
1 | #!/bin/sh |
beats + elasticsearch +logstash + kibana 这套工具集合出自于Elastic公司 https://www.elastic.co/guide/index.html
工具集功能
1 | http://localhost:9200/_template |
1 | http://localhost:9200/_cat/indices |
1 | http://localhost:9200/packetbeat-*/_search?pretty |
1 | http://localhost:5601/ |
1 | http://localhost:9200/_plugin/head/ |
1.删除模板
1 | curl -XDELETE 'http://localhost:9200/_template/packetbeat' |
2.上传模板
1 | curl -XPUT 'http://localhost:9200/_template/packetbeat' -d@/etc/packetbeat/packetbeat.template.json |
3.删除documents
1 | curl -XDELETE 'http://localhost:9200/packetbeat-*' |
一、上传原数据文件
将data.txt文件上传到到hdfs上,内容如下:
1 | key1 col1 value1 |
数据以制表符(\t)分割。
二、将数据写成HFile
通过mapredure将data.txt按hbase表格式写成hfile
pom.xml文件中依赖如下
1 | <!-- hadoop --> |
编写BulkLoadMapper
1 | public class BulkLoadMapper extends Mapper<LongWritable, Text, ImmutableBytesWritable, Put> { |
编写BulkLoadDriver
1 | public class BulkLoadDriver extends Configured implements Tool { |
整个项目需要将hbase-site.xml、yarn-site.xml、mapred-site.xml放入resources下。本地运行出错的话,再加入org.apache.hadoop.io.nativeio.NativeIO到当前工程中
三、数据加载
首先修改hadoop-env.sh配置,加入以下:
1 | export HBASE_HOME=/data/bigdata/hbase-1.0.0-cdh5.4.0 |
将数据按HFile写入到hdfs中,然后进入$HBASE_HOME/bin中执行以下命令
1 | /data/bigdata/hadoop-2.6.0-cdh5.4.0/bin/hadoop jar ../lib/hbase-server-1.0.0-cdh5.4.0.jar completebulkload /user/truman/hfile truman |
1 | public class HFileLoader { |
1 | [root@LAB3 bin]# ./hbase shell |
查看docker安装版本
2. docker search
查找opentsdb相关的镜像
1 | $ docker search opentsdb |
拉去镜像
1 | $ docker pull **/** |
查看当前机器运行的docker容器
构建镜像
1 | docker build -t=truman/redis:3.0.6 . |
1 | $ docker run ubuntu /bin/echo 'Hello world' |
参数 | 解释 |
---|---|
docker | 告诉操作系统我们要使用docker应用 |
docker run | 组合起来意思就是运行一个docker镜像 |
ubuntu | 镜像(image)名称 |
/bin/echo ‘Hello world’ | 告诉docker我们要在容器中执行的操作 |
之后我们就可以看到输出结果:Hello world |
1 | $ docker run -t -i ubuntu /bin/bash |
参数 | 解释 |
---|---|
-t | 为这个容器分配一个虚拟的终端 |
-i | 保持对于容器的stdin为打开的状态(输入)。 |
-d | 让docker容器在后台中运行 |
-p | 将docker容器内部端口映射到我们的host上面,我们可以使用 docker port CONTAINER_ID 来查询容器的端口 映射情况 |
一般情况下 -i 与 -t 参数都是结合在一起使用,这样交互会比较好一点。 |
这个参数是在容器生成的时候传入的,例如:指定hosts
1 | docker run -d -p 4244:4242 --name opentsdb5 --add-host lab1:192.168.0.101 --add-host lab2:192.168.0.102 --add-host lab3:192.168.0.103 truman/opentsdb |
都是在镜像名字之前传入的,可以写多个
6. docher start/stop/restart
该命令可以操作容器
7. docker rmi
强制删除镜像
1 | $ docker rmi -f <img_id> |
在容器以守护进程运行的过程中,可以通过docker logs命令查看log日志,具体用法如下:
1 | $ docker logs -ft <img_id> |
以终端模式查看最新log。还有其他命令:docker logs –tail 10
9. 更多命令
1 | Commands: |
所有指令都是大写
两个都是将本地文件复制到镜像中,区别是ADD可以指定绝对路径的文件,言外之意是可以上传除当前目录之外的文件。而COPY只能上传当前目录的文件。
这两条命令复制文件夹的话,只会讲子目录复制到指定目录下。例如
ADD redis3.0.4 /opt/app/redis/
只会将redis3.0.4下文件复制到redis目录下,不包含redis3.0.4目录。COPY同理
2. CMD,ENTRYPOINT
两个都是容器启动时运行的命令,区别是CMD可以被覆盖,而ENTRYPOINT不会。ENTRYPOINT只能是最后一个生效。
在开发过程中经常需要新建工程,新建工程使用自带的archetype,往往不能满足项目开发需求,这就需要我们开发出自己的archetype。
本次使用create-from-project来实现自定义archetype(方法至少两种)
首先使用eclipse创建一个新的maven project,然后把配置好的一些公用的东西放到相应的目录下面 比如说会将一些常用的java代码存放到src/main/java目录下面;会将一些通用的配置文件放到src/main/resources目录下面;如果是javeEE工程,还会有一些jsp等等的文件存放到src/main/webapp目录下面
在pom.xml文件中添加以下内容
1 | <build> |
在工程跟目录下运行maven命令
1 | mvn archetype:create-from-project |
然后会在target目录下面生成generated-sources目录,这个就是生成的 archetype
进入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命令。
如果想要卸载刚才安装的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 操作变慢,可按以下操作排除故障
获取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` |
查看redis中fdatasync(2),追踪进程
1 | sudo strace -p $(pidof redis-server) -T -e trace=fdatasync,write |
当数据库有超过1/4key在同一时间过期,会引起redis 阻塞
经过查看redis log,我们发现aof延迟比较厉害,猜测写aof影响了redis 性能。但为了保证数据安全,又无法关闭aof文件。经过查看官方文档,未更改aof保存策略维持fsync every second,更改
1 | no-appendfsync-on-rewrite yes |
这个配置是指在重写aof时,不持久化数据到aof中。
线上机器IO操作特别频繁,用命令
1 | iostat -d -k 2 |
查看当前IO情况。经过查看发现redis rdb temp文件变更比较频繁。将配置改为
1 | save 600 30000 |
线上机器IO才降下来。
经过测试,高并发情况下,key批量pipeline处理已经成为性能瓶颈。经过分析将这块的处理更改成并行处理,并行处理的线程数为当前master的数量,这样会将Client的处理能力提升n倍,经过测试,效果明显。
之前Client为了实时获取集群node信息,在每次操作都会主动获取集群信息。这里操作不用这么频繁,如果并发特别大的话,也会消耗大量的时间,经过分析后将此处做更改。有两种修改方法(1.)单独新建线程,专门维护集群信息(2.)更改成处理失败情况下,再去更新集群信息。目前采用第二种
系统如果不存在对操作时间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有很大帮助
实现一个线程最简单的方法
1 | new Thread() { |
runnable是一个接口类,使用的话,需要实现。
1 | new Thread(new Runnable() { |
Executors类,提供了一系列工厂方法用于创先线程池,返回的线程池都实现了ExecutorService接口。其中包括线程池,Executor,Executors,ExecutorService,CompletionService,Future,Callable等。
1 | ExecutorService executorService = Executors.newSingleThreadExecutor(); |
结合Future,Callable一起使用,可以取得多线程执行的返回值
1 | ExecutorService executorService = Executors.newFixedThreadPool(10); |
1 | ExecutorService executorService = Executors.newFixedThreadPool(10); |