首页 文章 精选 留言 我的

精选列表

搜索[指标分析],共10000篇文章
优秀的个人博客,低调大师

关于hive RegexSerDe的源码分析

最近有个业务建表使用了 RegexSerDe,之前虽然也它来解析nginx日志,但是没有做深入的了解。这次看了下其实现方式。 建表语句: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 CREATEexternalTABLEods_cart_log ( time_localSTRING, request_jsonSTRING, trace_id_numSTRING ) PARTITIONEDBY ( dtstring, hourstring ) ROWFORMATSERDE 'org.apache.hadoop.hive.contrib.serde2.RegexSerDe' WITHSERDEPROPERTIES ( "input.regex" = "\\\[(.*?)\\\].*\\\|(.*?)(.*?)\\\[(.*?)\\\]" , "output.format.string" = "%1$s%2$s%4$s" ) STOREDASTEXTFILE; 测试数据: 1 2 3 4 5 [2014-07-2415:54:54][6]OperationData.php: :89|{ "action" : "add" , "redis_key_hash" :9, "time" : "1406188494.73745500" , "source" : "web" , "mars_cid" : "" , "session_id" : "" , "info" :{ "cart_id" :26885, "user_id" :4, "size_id" : "2784145" , "num" : "1" , "warehouse" : "VIP_NH" , "brand_id" : "7379" , "cart_record_id" :26885, "channel" : "te" }} trace_id[40618849399972881308] 这里trace_id_num按照猜想应该是第4个字段(即40618849399972881308),但是实际输出了第3个字段(trace_id) 查看其代码实现: RegexSerDe主要由下面三个参数: 1)input.regex 正则 2)output.format.string 输出格式 3)input.regex.case.insensitive 大小写是否敏感 其中input.regex用在反序列化方法中,即数据的读取(hive读取hdfs文件),相对的output.format.string 用在序列化的方法中,即数据的写入(hive写入hdfs文件)。 在反序列化的方法deserialize中有如下代码,用于返回代表匹配字段的数据: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 for ( int c= 0 ;c<numColumns;c++){ //numColumns是按表中column的数量算的( 比如这个例子columnNames是[time_local,request_json,trace_id_num]|numColumns=columnNames.size(); try { row.set(c,m.group(c+ 1 )); //可以看到字段的匹配从0开始,中间不会有跳跃, 所以这里selecttrace_id_num字段是正则里面的第 3 个组,而和output.format.string没有关系 } catch (RuntimeExceptione){ partialMatchedRows++; if (partialMatchedRows>=nextPartialMatchedRows){ nextPartialMatchedRows=getNextNumberToDisplay(nextPartialMatchedRows); //Reporttherow LOG.warn( "" +partialMatchedRows + "partiallyunmatchedrowsarefound," + "cannotfindgroup" +c+ ":" +rowText); } row.set(c, null ); } } work around的方法有两个,1个是把所有正则匹配的字段列出,另一个就是更改正则的分组,只拿自己care的分组,比如上面可以改为 1 \\\[(.*?)\\\].*\\\|(.*?).*?\\\[(.*?)\\\] 这里output.format.string的设置仔细想想貌似没什么用,首先RegexSerDe的方式只在textfile下生效,即可以用load向hive的表中导入数据,但是load是一个hdfs层面的文件操作,不涉及到序列化,如果想使用序列化,需要使用insert into select的方式插入数据,但是这种方式插入的数据又和select的数据有关系,和output.format.string没什么关系了。。 其实regexserde类有两个 分别位于 1 ./serde/src/java/org/apache/hadoop/hive/serde2/RegexSerDe.java和 1 ./contrib/src/java/org/apache/hadoop/hive/contrib/serde2/RegexSerDe.java 都是扩展了AbstractSerDe这个抽象类。通过代码可以看到contrib下的这个类是实现了serialize和deserialize方法,而上面这个只实现了deserialize方法,由此看来RegexSerDe中的serialize方法可能是没什么用的。。 另外需要注意几点: 1.如果一行匹配不上,整个行的字段输出都是null 1 2 3 4 5 6 7 8 9 if (!m.matches()){ unmatchedRows++; if (unmatchedRows>=nextUnmatchedRows){ nextUnmatchedRows=getNextNumberToDisplay(nextUnmatchedRows); //Reporttherow LOG.warn( "" +unmatchedRows+ "unmatchedrowsarefound:" +rowText); } return null ; } 2.表的字段类型必须都是string,否则会报错,如果需要别的字段,可以在select中使用cast做转换 1 2 3 4 5 6 7 for ( int c= 0 ;c<numColumns;c++){ if (!columnTypes.get(c).equals(TypeInfoFactory.stringTypeInfo)){ throw new SerDeException(getClass().getName() + "onlyacceptsstringcolumns,butcolumn[" +c+ "]named" +columnNames.get(c)+ "hastype" +columnTypes.get(c)); } } 本文转自菜菜光 51CTO博客,原文链接:http://blog.51cto.com/caiguangguang/1532987,如需转载请自行联系原作者

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

苹果iPad2应用分析

iPad2设计很出色,使用起来相当方便,甚至成为送人的热门礼物。本人对iPad2的了解也是开始接触一段时间,但很快就熟悉了应用。对于想用和还没用上iPad2的朋友们,我们有必要先要了解一下iPad2的基础知识,这样才能更好的应用。 首先是iPad2的操作系统。iOS是由苹果公司开发的手持设备操作系统。苹果公司最早于2007年1月9日的Macworld大会上公布这个系统,最初是设计给iPhone使用的,后来陆续套用到iPod touch、iPad以及Apple TV等苹果产品上。iOS与苹果的Mac OS X操作系统一样,它也是以Darwin为基础的,因此同样属于类Unix的商业操作系统。原本这个系统名为iPhone OS,直到2010年6月7日WWDC大会上宣布改名为iOS。简单地说,ipad2、iphone4S、itouch用的都是这个操作系统,原理、界面、操作方法、设置基本上都大同小异,学会一个其他的就都明白了。iPad2的成功,离不了操作系统的设计,目前已经是iOS5的版本,升级这个最新的版本可以更好地省电,至于iOS的“越狱”,会导致系统宕机的情况出现。 我们如何同步ipad2应用和数据到自个的电脑里,这就要通过苹果的itunes软件,使用苹果数码产品都有通过itunes去同步,只有安装了itunes才能够通过电脑往苹果设备里安装软件、同步数据。不过使用itunes软件要保证网络畅通,不然会出现应用软件丢失,我们经常会通过itunes去自动同步音乐和照片,有时存放音乐的文件夹会变得很大,在设置同步时可以选择手动方式。 苹果的成千上万的Apps应用,也是ipad2最吸引人的地方,我们可以把Apps安装在iphone和iPad2之上,那么苹果是如何保护版权的呢?每个苹果设备都有唯一的Apple ID ,这个信息是唯一的硬件信息,可以保证未经验证不能下载Apps应用程序。Apple ID 是用户用来执行与 Apple 有关的所有操作(包括使用 iCloud 存储内容、从 App Store 下载应用程序以及从 iTunes Store 购买歌曲、影片和电视节目)的登录信息。 正是因为苹果有一个非常强大的电子出版交易平台,在苹果的同步软件“itunes”或者iphone、ipad2内置的“Apps Store”里面,在这个平台里不仅仅可以下载软件,而且还是一个巨大的电子出版物、数字音乐、数字电影的销售平台,一方面可以吸引应用开发者去发表,另一方面让用户付费去获得好的应用程序。所以,用户要使用itunes这个同步软件在苹果设备里来安装Apps,Apps来源于从“Apps store”中下载,苹果的设备在软件的安装和使用时都要去验证apple id,也就是说不管安装还是运行,苹果都会检查用户正在操作的这个软件,下载时的id和现在设备中的id是否一致,如果一致则可以运行,如果不一致就不能运行。 对于不想付费,却又想得到这些苹果Apps的方法只有“越狱”,后果是无法升级或是还原iOS,而且要忍受系统出现的宕机,“越狱”的原理是先想办法把一个后门程序不通过itunes安装进去,然后再通过这个后门程序解除验证机制,就一切搞定了。然后就可以在各个论坛、网站下载经过破解的软件,然后安装在iphone、ipad2上了,这样的话是没有苹果的服务保障。 iPad2 参数规格 外形尺寸:241.2×185.7×8.8mm 重量 601g 显示屏:屏幕尺寸 9.7英寸 分辨率 1024×768 屏幕描述:电容式触摸屏,多点式触摸屏 主要性能:处理器型号 A5 双核,1GHz 系统内存:512MB 音效:音频系统 立体声扬声器,内置麦克风 网络通信:WIFI无线/3G网络上网,支持802.11b/g/n无线协议 ,支持蓝牙2.1模块 接口:视频输出 mini HDMI接口 其他接口: 3.5毫米耳机插孔,苹果Dock接口 电池类型:锂电池 续航时间 约10小时(连续运行游戏或视频) 操作系统:Phone OS 本文转自 zhaiken 51CTO博客,原文链接:http://blog.51cto.com/zhaiken/752443,如需转载请自行联系原作者

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

MapReduce过程详细分析

Shuffle产生的意义是什么?Shuffle过程的期望可以有:完整地从map task端拉取数据到reduce 端。在跨节点拉取数据时,尽可能地减少对带宽的不必要消耗。减少磁盘IO对task执行的影响。每个map task都有一个内存缓冲区,存储着map的输出结果,当缓冲区快满的时候需要将缓冲区的数据该如何处理?每个map task都有一个内存缓冲区,存储着map的输出结果,当缓冲区快满的时候需要将缓冲区的数据以一个临时文件的方式存放到磁盘,当整个map task结束后再对磁盘中这个map task产生的所有临时文件做合并,生成最终的正式输出文件,然后等待reduce task来拉数据。MapReduce提供Partitioner接口,它的作用是什么?MapReduce提供Partitioner接口,它的作用就是根据key或value及reduce的数量来决定当前的这对输出数据最终应该交由哪个reduce task处理。默认对key hash后再以reduce task数量取模。默认的取模方式只是为了平均reduce的处理能力,如果用户自己对Partitioner有需求,可以订制并设置到job上。什么是溢写?在一定条件下将缓冲区中的数据临时写入磁盘,然后重新利用这块缓冲区。这个从内存往磁盘写数据的过程被称为Spill,中文可译为溢写。溢写是为什么不影响往缓冲区写map结果的线程?溢写线程启动时不应该阻止map的结果输出,所以整个缓冲区有个溢写的比例spill.percent。这个比例默认是0.8,也就是当缓冲区的数据已经达到阈值(buffer size * spill percent = 100MB * 0.8 = 80MB),溢写线程启动,锁定这80MB的内存,执行溢写过程。Map task的输出结果还可以往剩下的20MB内存中写,互不影响。当溢写线程启动后,需要对这80MB空间内的key做排序(Sort)。排序是MapReduce模型默认的行为,这里的排序也是对谁的排序?当溢写线程启动后,需要对这80MB空间内的key做排序(Sort)。排序是MapReduce模型默认的行为,这里的排序也是对序列化的字节做的排序。溢写过程中如果有很多个key/value对需要发送到某个reduce端去,那么如何处理这些key/value值?如果有很多个key/value对需要发送到某个reduce端去,那么需要将这些key/value值拼接到一块,减少与partition相关的索引记录。哪些场景才能使用Combiner呢?Combiner的输出是Reducer的输入,Combiner绝不能改变最终的计算结果。所以从我的想法来看,Combiner只应该用于那种Reduce的输入key/value与输出key/value类型完全一致,且不影响最终结果的场景。比如累加,最大值等。Combiner的使用一定得慎重,如果用好,它对job执行效率有帮助,反之会影响reduce的最终结果。Merge的作用是什么?最终磁盘中会至少有一个这样的溢写文件存在(如果map的输出结果很少,当map执行完成时,只会产生一个溢写文件),因为最终的文件只有一个,所以需要将这些溢写文件归并到一起,这个过程就叫做Merge每个reduce task不断的通过什么协议从JobTracker那里获取map task是否完成的信息?每个reduce task不断地通过RPC从JobTracker那里获取map task是否完成的信息reduce中Copy过程采用是什么协议?Copy过程,简单地拉取数据。Reduce进程启动一些数据copy线程(Fetcher),通过HTTP方式请求map task所在的TaskTracker获取map task的输出文件。reduce中merge过程有几种方式?merge有三种形式:1)内存到内存2)内存到磁盘3)磁盘到磁盘。默认情况下第一种形式不启用,让人比较困惑,是吧。当内存中的数据量到达一定阈值,就启动内存到磁盘的merge。与map 端类似,这也是溢写的过程,这个过程中如果你设置有Combiner,也是会启用的,然后在磁盘中生成了众多的溢写文件。第二种merge方式一直在运行,直到没有map端的数据时才结束,然后启动第三种磁盘到磁盘的merge方式生成最终的那个文件。 本文转自 ChinaUnicom110 51CTO博客,原文链接:http://blog.51cto.com/xingyue2011/1951558

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

Android SDCard UnMounted 流程分析(二)

上一篇讲到通过NetlinkManager发送uevent 命令到NetlinkHandler 的onEvent,代码如下: voidNetlinkHandler::onEvent(NetlinkEvent*evt){ VolumeManager*vm=VolumeManager::Instance(); const char*subsys=evt->getSubsystem(); if(!subsys){ SLOGW( " Nosubsystemfoundinnetlinkevent "); return; } SLOGD( " NetlinkHandler:OnEventsubsysvaluesis%s ",subsys); if(!strcmp(subsys, " block ")){ SLOGD( " NetlinkHandler:onEvent "); vm->handleBlockEvent(evt); } } 在NetlinkHandler 里面得一个VolumeManager,当收到的命令为block时调用VolumnManager的handleBlockEvent,如上加红加粗的代码。 handleBlockEvent实则是通过一个循环将事先将main事先读取的配置文件:etc/vold.fstab存进VolumeCollection,得到VolumeCollection的对象,然后调用Volume 的handleBlockEvent,如代码: voidVolumeManager::handleBlockEvent(NetlinkEvent*evt){ const char*devpath=evt->findParam( " DEVPATH "); /* Lookupavolumetohandlethisdevice */ VolumeCollection::iteratorit; boolhit= false; for(it=mVolumes->begin();it!=mVolumes->end();++it){ if(! (*it)->handleBlockEvent(evt)){ #ifdefNETLINK_DEBUG SLOGD( " Device'%s'eventhandledbyvolume%s\n ",devpath,(*it)->getLabel()); #endif hit= true; break; } } if(!hit){ #ifdefNETLINK_DEBUG SLOGW( " Novolumeshandledblockeventfor'%s' ",devpath); #endif } 看一下Volume 的handleblockEvent代码: intVolume::handleBlockEvent(NetlinkEvent*evt){ errno=ENOSYS; return- 1; 看起来好像没做什么事,其实真的实现在于Volume 的子类,DirectVolume,DirectVolme 中重写了handleBlockEvent,看代码: intDirectVolume::handleBlockEvent(NetlinkEvent*evt){ const char*dp=evt->findParam( " DEVPATH "); PathCollection::iteratorit; for(it=mPaths->begin();it!=mPaths->end();++it){ if(!strncmp(dp,*it,strlen(*it))){ /* Wecanhandlethisdisk */ intaction=evt->getAction(); const char*devtype=evt->findParam( " DEVTYPE "); if(action==NetlinkEvent::NlActionAdd){ intmajor=atoi(evt->findParam( " MAJOR ")); intminor=atoi(evt->findParam( " MINOR ")); charnodepath[ 255]; snprintf(nodepath, sizeof(nodepath), " /dev/block/vold/%d:%d ", major,minor); if(createDeviceNode(nodepath,major,minor)){ SLOGE( " Errormakingdevicenode'%s'(%s) ",nodepath, strerror(errno)); } if(!strcmp(devtype, " disk ")){ handleDiskAdded(dp,evt); } else{ handlePartitionAdded(dp,evt); } } else if(action==NetlinkEvent::NlActionRemove){ if(!strcmp(devtype, " disk ")){ handleDiskRemoved(dp,evt); } else{ SLOGD( " DirectVolume:handleBlockEvent--->handlePartitionRemoved "); handlePartitionRemoved(dp,evt); } } else if(action==NetlinkEvent::NlActionChange){ if(!strcmp(devtype, " disk ")){ handleDiskChanged(dp,evt); } else{ handlePartitionChanged(dp,evt); } } else{ SLOGW( " Ignoringnonadd/remove/changeevent "); } return 0; } } errno=ENODEV; return- 1; } 因为我的板子还未完善,所以这里它认为我的sdcard是一个分区,但无关紧要,原理一样,就根据分区的代码跟踪。:handlePartitionRemoved,由于代码过多,只贴出核心代码: voidDirectVolume::handlePartitionRemoved( const char*devpath,NetlinkEvent*evt){ if((dev_t)MKDEV(major,minor)==mCurrentlyMountedKdev){ /* *Yikes,ourmountedpartitionisgoingaway! */ snprintf(msg, sizeof(msg), " Volume%s%sbadremoval(%d:%d) ", getLabel(),getMountpoint(),major,minor); SLOGD( " DirectVolume:(dev_t)MKDEV(major,minor)==mCurrentlyMountedKdev:%d,msgis:%s. ",mCurrentlyMountedKdev,msg); mVm->getBroadcaster()->sendBroadcast(ResponseCode::VolumeBadRemoval,msg,false); if(mVm->cleanupAsec( this, true)){ SLOGE( " FailedtocleanupASEC-unmountwillprobablyfail! "); } if( Volume::unmountVol(true,false)){ SLOGE( " Failedtounmountvolumeonbadremoval(%s) ", strerror(errno)); // XXX:Atthispointwe'rescrewedfornow } else{ SLOGD( " Crisisaverted "); } } } 到此,直接调用父类的unmountVol方法,unmountVol会通过setState通知框架状态改变。代码太多,只推荐核心代码: intVolume::unmountVol( boolforce, boolrevert){ setState(Volume::State_Unmounting); } 而setState会通过socket将msg消息传给框架 mVm->getBroadcaster()->sendBroadcast(ResponseCode::VolumeStateChange, msg, false); 接下去的步骤是关于socket的操作,就不深入了。 小结 到了这一步,Vold 向上层反馈的动作基本己经完成,下一篇文章将会讲解Framework 如何取得Vold 反馈过来的数据。 本文转自 terry_龙 51CTO博客,原文链接:http://blog.51cto.com/terryblog/814963 ,如需转载请自行联系原作者

资源下载

更多资源
腾讯云软件源

腾讯云软件源

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

Nacos

Nacos

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

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

用户登录
用户注册