首页 文章 精选 留言 我的

精选列表

搜索[读写分离],共10005篇文章
优秀的个人博客,低调大师

使用Hive读写ElasticSearch中的数据(转载)

转自:http://lxw1234.com/archives/2015/12/585.htm 关键字:hive、elasticsearch、integration、整合 ElasticSearch已经可以与YARN、Hadoop、Hive、Pig、Spark、Flume等大数据技术框架整合起来使用,尤其是在添加数据的时候,可以使用分布式任务来添加索引数据,尤其是在数据平台上,很多数据存储在Hive中,使用Hive操作ElasticSearch中的数据,将极大的方便开发人员。这里记录一下Hive与ElasticSearch整合,查询和添加数据的配置使用过程。基于Hive0.13.1、Hadoop-cdh5.0、ElasticSearch 2.1.0。 通过Hive读取与统计分析ElasticSearch中的数据 ElasticSearch中已有的数据 _index:lxw1234 _type:tags _id:用户ID(cookieid) 字段:area、media_view_tags、interest Hive建表 由于我用的ElasticSearch版本为2.1.0,因此必须使用elasticsearch-hadoop-2.2.0才能支持,如果ES版本低于2.1.0,可以使用elasticsearch-hadoop-2.1.2. 下载地址:https://www.elastic.co/downloads/hadoop add jar file:///home/liuxiaowen/elasticsearch-hadoop-2.2.0-beta1/dist/elasticsearch-hadoop-hive-2.2.0-beta1.jar; CREATE EXTERNAL TABLE lxw1234_es_tags( cookieidstring, areastring, media_view_tagsstring, intereststring ) STORED BY'org.elasticsearch.hadoop.hive.EsStorageHandler' TBLPROPERTIES( 'es.nodes'='172.16.212.17:9200,172.16.212.102:9200', 'es.index.auto.create'='false', 'es.resource'='lxw1234/tags', 'es.read.metadata'='true', 'es.mapping.names'='cookieid:_metadata._id, area:area, media_view_tags:media_view_tags, interest:interest'); 注意:因为在ES中,lxw1234/tags的_id为cookieid,要想把_id映射到Hive表字段中,必须使用这种方式: ‘es.read.metadata’ = ‘true’, ‘es.mapping.names’ = ‘cookieid:_metadata._id,…’ 在Hive中查询数据 数据已经可以正常查询。 执行SELECT COUNT(1) FROM lxw1234_es_tags;Hive还是通过MapReduce来执行,每个分片使用一个Map任务: 可以通过在Hive外部表中指定search条件,只查询过滤后的数据。比如,下面的建表语句会从ES中搜索_id=98E5D2DE059F1D563D8565的记录: CREATE EXTERNAL TABLE lxw1234_es_tags_2( cookieidstring, areastring, media_view_tagsstring, intereststring ) STORED BY'org.elasticsearch.hadoop.hive.EsStorageHandler' TBLPROPERTIES( 'es.nodes'='172.16.212.17:9200,172.16.212.102:9200', 'es.index.auto.create'='false', 'es.resource'='lxw1234/tags', 'es.read.metadata'='true', 'es.mapping.names'='cookieid:_metadata._id, area:area, media_view_tags:media_view_tags, interest:interest', 'es.query'='?q=_id:98E5D2DE059F1D563D8565' ); hive>select*fromlxw1234_es_tags_2; OK 98E5D2DE059F1D563D8565四川|成都购物|1购物|1 Timetaken:0.096seconds,Fetched:1row(s) 如果数据量不大,可以使用Hive的Local模式来执行,这样不必提交到Hadoop集群: 在Hive中设置: sethive.exec.mode.local.auto.inputbytes.max=134217728; sethive.exec.mode.local.auto.tasks.max=10; sethive.exec.mode.local.auto=true; setfs.defaultFS=file:///; hive>selectarea,count(1)ascntfromlxw1234_es_tagsgroupbyarea orderbycnt desc limit20; Automaticallyselectinglocalonly modeforquery Totaljobs=2 LaunchingJob1outof2 ….. Executionlog at:/tmp/liuxiaowen/liuxiaowen_20151211133030_97b50138-d55d-4a39-bc8e-cbdf09e33ee6.log Jobrunningin-process(localHadoop) Hadoopjob informationfornull:number of mappers:0;number of reducers:0 2015-12-1113:30:59,648nullmap=100%,reduce=100% EndedJob=job_local1283765460_0001 Executioncompleted successfully MapredLocaltask succeeded OK 北京|北京10 四川|成都4 重庆|重庆3 山西|太原3 上海|上海3 广东|深圳3 湖北|武汉2 陕西|西安2 福建|厦门2 广东|中山2 福建|三明2 山东|济宁2 甘肃|兰州2 安徽|合肥2 湖南|长沙2 湖南|湘西2 河南|洛阳2 江苏|南京2 黑龙江|哈尔滨2 广西|南宁2 Timetaken:13.037seconds,Fetched:20row(s) hive> 很快完成了查询与统计。 通过Hive向ElasticSearch中写数据 Hive建表 add jar file:///home/liuxiaowen/elasticsearch-hadoop-2.2.0-beta1/dist/elasticsearch-hadoop-hive-2.2.0-beta1.jar; CREATE EXTERNAL TABLE lxw1234_es_user_tags( cookieidstring, areastring, gendercode STRING, birthday STRING, jobtitle STRING, familystatuscode STRING, haschildrencode STRING, media_view_tagsstring, order_click_tags STRING, search_egine_tags STRING, intereststring) STORED BY'org.elasticsearch.hadoop.hive.EsStorageHandler' TBLPROPERTIES( 'es.nodes'='172.16.212.17:9200,172.16.212.102:9200', 'es.index.auto.create'='true', 'es.resource'='lxw1234/user_tags', 'es.mapping.id'='cookieid', 'es.mapping.names'='area:area, gendercode:gendercode, birthday:birthday, jobtitle:jobtitle, familystatuscode:familystatuscode, haschildrencode:haschildrencode, media_view_tags:media_view_tags, order_click_tags:order_click_tags, search_egine_tags:search_egine_tags, interest:interest'); 这里要注意下:如果是往_id中插入数据,需要设置’es.mapping.id’ = ‘cookieid’参数,表示Hive中的cookieid字段对应到ES中的_id,而es.mapping.names中不需要再映射,这点和读取时候的配置不一样。 关闭Hive推测执行,执行INSERT: SET hive.mapred.reduce.tasks.speculative.execution=false; SET mapreduce.map.speculative=false; SET mapreduce.reduce.speculative=false; INSERT overwrite TABLE lxw1234_es_user_tags SELECT cookieid, area, gendercode, birthday, jobtitle, familystatuscode, haschildrencode, media_view_tags, order_click_tags, search_egine_tags, interest FROM source_table; 注意:如果ES集群规模小,而source_table数据量特别大、Map任务数太多的时候,会引发错误: Causedby:org.elasticsearch.hadoop.rest.EsHadoopInvalidRequest: FOUND unrecoverable error[172.16.212.17:9200]returnedTooManyRequests(429)-rejected execution of org.elasticsearch.action.support.replication.TransportReplicationAction$PrimaryPhase$1@b6fa90f ONEsThreadPoolExecutor[bulk,queue capacity=50, org.elasticsearch.common.util.concurrent.EsThreadPoolExecutor@22e73289[Running,pool size=32,active threads=32,queued tasks=52,completed tasks=12505]]; Bailingout.. 原因是Map任务数太多,并发发送至ES的请求数过多。 这个和ES集群规模以及bulk参数设置有关,目前还没弄明白。 减少source_table数据量(即减少Map任务数)之后,没有出现这个错误。 执行完成后,在ES中查询lxw1234/user_tags的数据: curl-XGET http://172.16.212.17:9200/lxw1234/user_tags/_search?pretty -d ' { "query":{ "match":{ "area":"成都" } } }' 数据已经写入到ElasticSearch中。 总结 使用Hive将数据添加到ElasticSearch中还是非常实用的,因为我们的数据都是在HDFS上,通过Hive可以查询的。 另外,通过Hive可以查询ES数据,并在其上做复杂的统计与分析,但性能一般,比不上使用ES原生API,亦或是还没有掌握使用技巧,后面继续研究。 相关阅读: ElasticSearch集群安装配置 ElasticSearch与Hive整合官方文档

优秀的个人博客,低调大师

Hadoop SequenceFile数据结构介绍及读写

在一些应用中,我们需要一种特殊的数据结构来存储数据,并进行读取,这里就分析下为什么用SequenceFile格式文件。 Hadoop SequenceFile Hadoop提供的SequenceFile文件格式提供一对key,value形式的不可变的数据结构。同时,HDFS和MapReduce job使用SequenceFile文件可以使文件的读取更加效率。 SequenceFile的格式 SequenceFile的格式是由一个header 跟随一个或多个记录组成。前三个字节是一个Bytes SEQ代表着版本号,同时header也包括key的名称,value class , 压缩细节,metadata,以及Sync markers。Sync markers的作用在于可以读取任意位置的数据。 在recourds中,又分为是否压缩格式。当没有被压缩时,key与value使用Serialization序列化写入SequenceFile。当选择压缩格式时,record的压缩格式与没有压缩其实不尽相同,除了value的bytes被压缩,key是不被压缩的。 在Block中,它使所有的信息进行压缩,压缩的最小大小由配置文件中,io.seqfile.compress.blocksize配置项决定。 SequenceFile的MapFile 一个MapFile可以通过SequenceFile的地址,进行分类查找的格式。使用这个格式的优点在于,首先会将SequenceFile中的地址都加载入内存,并且进行了key值排序,从而提供更快的数据查找。 写SequenceFile文件: 将key按100-1以IntWritable object进行倒叙写入sequence file,value为Text objects格式。在将key和value写入Sequence File前,首先将每行所在的位置写入(writer.getLength()) import org.apache.hadoop.conf.Configuration;import org.apache.hadoop.fs.FileSystem;import org.apache.hadoop.fs.Path;import org.apache.hadoop.io.IOUtils;import org.apache.hadoop.io.IntWritable;import org.apache.hadoop.io.SequenceFile;import org.apache.hadoop.io.Text; import java.io.IOException;import java.net.URI; public class SequenceFileWriteDemo { private static final String[] DATA = { "One, two, buckle my shoe", "Three, four, shut the door", "Five, six, pick up sticks", "Seven, eight, lay them straight", "Nine, ten, a big fat hen" }; public static void main(String[] args) throws IOException { String uri = args[0]; Configuration conf = new Configuration(); FileSystem fs = FileSystem.get(URI.create(uri), conf); Path path = new Path(uri); IntWritable key = new IntWritable(); Text value = new Text(); SequenceFile.Writer writer = null; try { writer = SequenceFile.createWriter(fs, conf, path, key.getClass(), value.getClass()); for (int i = 0; i < 100; i++) { key.set(100 - i); value.set(DATA[i % DATA.length]); System.out.printf("[%s]\t%s\t%s\n", writer.getLength(), key, value); writer.append(key, value); } } finally { IOUtils.closeStream(writer); } } } 读取SequenceFile文件: 首先需要创建SequenceFile.Reader实例,随后通过调用next()函数进行每行结果集的迭代(需要依赖序列化). import org.apache.hadoop.conf.Configuration;import org.apache.hadoop.fs.FileSystem;import org.apache.hadoop.fs.Path;import org.apache.hadoop.io.IOUtils;import org.apache.hadoop.io.SequenceFile;import org.apache.hadoop.io.Writable;import org.apache.hadoop.util.ReflectionUtils; import java.io.IOException;import java.net.URI; public class SequenceFileReadDemo { public static void main(String[] args) throws IOException { String uri = args[0]; Configuration conf = new Configuration(); FileSystem fs = FileSystem.get(URI.create(uri), conf); Path path = new Path(uri); SequenceFile.Reader reader = null; try { reader = new SequenceFile.Reader(fs, path, conf); Writable key = (Writable) ReflectionUtils.newInstance(reader.getKeyClass(), conf); Writable value = (Writable) ReflectionUtils.newInstance(reader.getValueClass(), conf); long position = reader.getPosition(); while (reader.next(key, value)) { //同步记录的边界 String syncSeen = reader.syncSeen() ? "*" : ""; System.out.printf("[%s%s]\t%s\t%s\n", position, syncSeen, key, value); position = reader.getPosition(); // beginning of next record } } finally { IOUtils.closeStream(reader); } } } 参考文献: 《Hadoop:The Definitive Guide, 4th Edition》

优秀的个人博客,低调大师

apiCloud中实现头部与内容分离与操作规范,App头部header固定,头部与内容分离

官方案例 1.头部拆分成一个页面比如news-text <!doctype html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="initial-scale=1.0,maximum-scale=1.0,minimum-scale=1.0,user-scalable=0, width=device-width"/> <title>api</title> <link rel="stylesheet" type="text/css" href="../css/api.css" /> <link rel="stylesheet" type="text/css" href="../css/common.css" /> <link rel="stylesheet" type="text/css" href="../css/news-text.css" /> </head> <body> <div id="wrap"> <div id="header"> <a class="back-icon" tapmode="" onclick="api.closeWin()"></a> <h1>热点新闻</h1> </div> </div> </body> <script type="text/javascript" src="../script/api.js"></script> <script type="text/javascript" src="../script/news-text.js"></script> </html> 2.内容拆分成另一个页面比如news-textCon <!doctype html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="initial-scale=1.0,maximum-scale=1.0,minimum-scale=1.0,user-scalable=0, width=device-width"/> <title>api</title> <link rel="stylesheet" type="text/css" href="../css/api.css" /> <link rel="stylesheet" type="text/css" href="../css/common.css" /> <link rel="stylesheet" type="text/css" href="../css/news-text.css" /> </head> <body> <div id="wrap"> <div id="main"> <script id="news-template" type="text/x-dot-template"> <h1>{{=it.title}}</h1> <label> {{? it.from }} {{=it.from}} {{?}} <em>{{=it.date}}</em> </label> <div id="summary"> {{=it.summary}} </div> <div> {{=it.content}} </div> <a id="fav" class="btn" tapmode="active" news-id="{{=it.id}}" >收藏</a> </script> <div id="content"></div> </div> </div> </body> <script type="text/javascript" src="../script/api.js"></script> <script type="text/javascript" src="../script/common.js"></script> <script type="text/javascript" src="../script/doT.min.js"></script> <script type="text/javascript" src="../script/zepto.js"></script> <script type="text/javascript" src="../script/news-textCon.js"></script> </html> 以上就是一个非常规范的内容 1.css在头部 引入必要的css,api.css 引入通用的css,common.css 引入页面特有的css,news-text.css 2.js在尾部 引入必要的css,api.js 引入通用的css,common.js 引入页面特有的css,news-text.js 根据页面需要,引入doT模板和zepto(手机端的jQuery替代品) 来看看news-text.js中的内容 apiready = function(){ var header = $api.byId('header'); // 获取头部 $api.fixStatusBar(header); // 处理ios兼容 var newsId = api.pageParam.newsId; // 获取参数 var pos = $api.offset(header); // 获取位置数据 api.openFrame({ // 打开Frame name: 'news-textCon', url: 'news-textCon.html', pageParam: {newsId: newsId}, // 传递参数 rect:{ x: 0, y: pos.h, // 头部留位置 w: 'auto', h: 'auto' }, bounces: true, vScrollBarEnabled: false }); }; 打开frame,保证头部留有位置,同时可以传递参数 再看看news-textCon.js中的内容 apiready = function () { var newsId = api.pageParam.newsId; // 获取参数 var getNewsByIdUrl = '/news/?filter='; var urlParam = {where: {id: newsId}}; api.showProgress({ title: '加载中...', modal: false }); ajaxRequest(getNewsByIdUrl+JSON.stringify(urlParam),'get','',function(ret,err){ if (ret) { api.toast({ ... }) } else { api.toast({ ... }) } api.hideProgress(); }); }; 获取传入的参数, 获取数据与相应的页面处理 我的案例 商品详情拆分 1.goods_detail.html <!doctype html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="initial-scale=1.0,maximum-scale=1.0,minimum-scale=1.0,user-scalable=0, width=device-width"/> <title>api</title> <link rel="stylesheet" type="text/css" href="../css/api.css" /> <link rel="stylesheet" type="text/css" href="../css/aui.2.0.css" /> </head> <body> <div id="wrap"> <div id="main"> <header class="aui-bar aui-bar-nav fix-status-bar" id="aui-header"> <a class="aui-btn aui-pull-left" tapmode onclick="api.closeWin();"> <span class="aui-iconfont aui-icon-left"></span> </a> <div class="aui-title"><!-- 商品名称 --></div> </header> </div> </div> </body> <script type="text/javascript" src="../script/api.js"></script> <script type="text/javascript" src="../script/goods_detail.js"></script> </html> 2.goods_detailCon.html 移除头部的 <header class="aui-bar aui-bar-nav fix-status-bar" id="aui-header"> <a class="aui-btn aui-pull-left" tapmode onclick="api.closeWin();"> <span class="aui-iconfont aui-icon-left"></span> </a> <div class="aui-title"><!-- 商品名称 --></div> </header> 3.goods_detail.js apiready = function(){ var header = $api.byId('main'); // 获取头部 $api.fixStatusBar(header); // 处理ios var pos = $api.offset(header); // 获取头部位置 var title = $api.dom(header,'.aui-title'); // 获取标题位置 $api.html(title,api.pageParam.title); // 设置标题内容 api.openFrame({ // 打开内容页,并传递参数 name: 'goods_detailCon', url: 'goods_detailCon.html', rect:{ x: 0, y: pos.h, w: 'auto', h: 'auto' }, bounces: true, opaque: true, vScrollBarEnabled: false, pageParam:{ goods_id:api.pageParam.goods_id } }); }; 4.goods_detailCon.js apiready = function(){ fix_status_bar();// 修复头部 var goods_id = api.pageParam.goods_id; // 获取商品相关信息 api.ajax({ url: 'http://zhudianbao.yunlutong.com/?g=Api&m=Goods&a=getGoodsInfo', method: 'get', data: { values: { goods_id: goods_id } } }, function(json, err) { if (json.status == '1') { var interText = doT.template($("#goodstmpl").text()); $("#info_area").html(interText(json.info)); var swiper = new Swiper('.swiper-container', { pagination: '.swiper-pagination', paginationClickable: true, spaceBetween: 30, centeredSlides: true, autoplay: 3500, autoplayDisableOnInteraction: false }); } else { var toast = new auiToast(); toast.fail({ title:json.msg, duration:2000 }); } }); } 获取参数,根据参数获取数据,并使用doT进行页面布局。 看效果 本文转自TBHacker博客园博客,原文链接:http://www.cnblogs.com/jiqing9006/p/5952935.html,如需转载请自行联系原作者

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。