首页 文章 精选 留言 我的

精选列表

搜索[学习],共10000篇文章
优秀的个人博客,低调大师

学习了《python网络爬虫实战》第一个爬虫,爬取新浪新闻

请安装anaconda,其中附带的spyder方便运行完查看变量 1.进入cmd控制台, 输入 pip install BeautifulSoup4 pip install requests 2.编写代码,代码已经很清晰了,直接运行不会报错并有成功的结果 def getNewsDetail(newsUrl): import requests from bs4 import BeautifulSoup from datetime import datetime newsWeb = requests.get(newsUrl) newsWeb.encoding = 'utf-8' soup = BeautifulSoup(newsWeb.text,'lxml') result = {} result['title'] = soup.select('.main-title')[0].text result['newsSource'] = soup.select('.source')[0].text timeSource = soup.select('.date')[0].text result['datetime'] = datetime.strptime(timeSource,'%Y年%m月%d日 %H:%M') result['article'] = soup.select('.article')[0].text result['editor'] = soup.select('.show_author')[0].text.strip('责任编辑:') result['comment'] = soup.select('.num')[0].text return result def parseListLinks(url): import requests import json newsDetails = [] request = requests.get(url) jsonLoad = json.loads(request.text.lstrip(' newsloadercallback(').rstrip(');')) newsUrls = [] for item in jsonLoad['result']['data']: newsUrls.append(item['url']) for url in newsUrls: newsDetails.append(getNewsDetail(url)) return newsDetails if __name__ == '__main__': #获取单个新闻页面的信息 newsUrl = 'http://news.sina.com.cn/s/wh/2018-01-08/doc-ifyqkarr7830426.shtml' newsDetail = getNewsDetail(newsUrl) #获取整个列表各个新闻页面的信息 rollUrl='http://api.roll.news.sina.com.cn/zt_list?channel=news&cat_1=gnxw\ &cat_2==gdxw1||=gatxw||=zs-pl||=mtjj&level==1||=2&show_ext=1&show_all=1&\ show_num=22&tag=1&format=json&page=23&callback=newsloadercallback&_=1515911333929' newsDetails = parseListLinks(rollUrl)

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

【案例学习】美国大都会人寿保险公司的 Docker EE 实践

写在前面 MetLife(美国大都会人寿保险公司)是一家拥有150年历史的公司,它是领先的保险及其它金融服务的提供商,为遍布全美的数以百万计的个人和企业客户提供服务,包括美国财富五百强中排名前100位的88家公司。作为一家全球性公司,MetLife 向世界各地提供金融、保险服务——其中有一些是终身服务。有着如此庞大的业务规模,MetLife 需要多种组合的IT基础设施来维持它的日常运作。 降低现有的技术运维成本 今年4月,来自 MetLife 的亚伦·艾代斯(Aaron Aedes)谈到了他们第一次涉足 Docker 容器的经历——即使用一款通过Azure 交付的名为 GSSP 的新应用程序。六个月后,MetLife 来到 DockerCon 欧洲大会的舞台并分享他们使用 Docker 容器的经验——从最初的部署到促使他们主动寻找在 M

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

Hadoop MapReduce概念学习系列之十分钟看透MapReduce(十一)

我们已经知道了Hadoop的三大核心模块:HDFS、MapReduce、Yarn。 MapReduce是什么? MapReduce是一种编程模型,用于大规模数据集的并行计算,其主要思想就是Map(映射)和Reduce(化简)。 MapReduce的创意和灵感来源于函数式编程,在函数式编程中,map对列表的每个元素执行操作或函数。例如:列表[1,2,3,4]上执行 multiple-by-two 函数会产生另一个列表[2,4,6,8],执行时,原列表不被改变。函数式编程认为,应当保持数据不可变,避免在多个进程或线程间共享数据。这意味着,这个函数虽然简单,但可以通过两个或更多线程在同一列表上同时执行,线程间互不影响,因为列表本身未被改变。 MapReduce是用来进行海量数据的并行计算的,需要将工作分配到大量的机器上去做,如果组件间可共享数据,那么数据节点间的数据同步会使系统变得低效且不可靠。实际上,MapReduce上的数据元素是不可变的,即便改变也不会反馈到输入文件,节点间通信只在新的键值对输出时发生,Hadoop会把输出键值对传到下一个阶段。 从概念上讲,MapReduce程序将输入数据列表转变成输出数据列表。一个MapReduce程序会执行两次数据转换操作,一次map,一次reduce。还是举个例子吧: ***********************数据来源****************************** 1 wolys@21cn.com 2 zss1984@126.com 3 294522652@qq.com 4 simulateboy@163.com 5 zhoushigang_123@163.com 6 sirenxing424@126.com 7 lixinyu23@qq.com 8 chenlei1201@gmail.com 9 370433835@qq.com 10 cxx0409@126.com 11 viv093@sina.com 12 q62148830@163.com 13 65993266@qq.com 14 summeredison@sohu.com 15 zhangbao-autumn@163.com 16 diduo_007@yahoo.com.cn 17 fxh852@163.com 18 weiyang1128@163.com 19 licaijun007@163.com 20 junhongshouji@126.com 21 wuxiaohong11111@163.com 22 fennal@sina.com 23 li_dao888@163.com 24 bokil.xu@163.com 25 362212053@qq.com 26 youloveyingying@yahoo.cn 27 boiny@126.com 28 linlixian200606@126.com 29 alex126126@126.com 30 654468252@qq.com 31 huangdaqiao@yahoo.com.cn 32 kitty12502@163.com 33 xl200811@sohu.com 34 ysjd8@163.com 35 851627938@qq.com 36 wubo_1225@163.com 37 kangtezc@163.com 38 xiao2018@126.com 39 121641873@qq.com 40 296489419@qq.com 41 beibeilong012@126.com 第一步:map。读取输入文件内容,解析成key、value对。对输入文件的每一行,解析成key、value对。通过‘@’对value解析出邮箱域。即邮箱账号的@符号后面部分 <21cn.com 1> <126.com 1> <qq.com 1> <163.com 1> <163.com 1> <126.com 1> <qq.com 1> <gmail.com 1> .......... 第二步:combine。对相同的邮箱域合并。 <163.com 1 1 1 1 1 1 1 1 1 1 1 1 1 1> <126.com 1 1 1 1 1 1 1 1 1> <qq.com 1 1 1 1 1 1 1 1 1> <sina.com 1 1> <sohu.com 1 1> <yahoo.com.cn 1 1> <21cn.com 1> <gmail.com 1> <yahoo.cn 1> 第三步:reduce。对相同的邮箱域统计求和。 <163.com 14> <126.com 9> <qq.com 9> <sina.com 2> <sohu.com 2> <yahoo.com.cn 2> <21cn.com 1> <gmail.com 1> <yahoo.cn 1> 好了,我们想要的结果出来了。MapReduce的思想从根源上讲也就是如此,是不是很简单呀? MapReduce的基本流程 MapReduce计算模型由两个阶段组成:Map和Reduce,用户只需要实现map()和reduce()两个函数,即可实现分布式计算,非常简单。 图1 统计图形样式个数的map和reduce过程示意图 map()和reduce()这两个函数的形参是key、value对,表示函数的输入信息。 1. map任务处理 1.1 读取输入文件内容,解析成key、value对。对输入文件的每一行,解析成key、value对。每一个键值对调用一次map函数。 1.2 写自己的逻辑,对输入的key、value处理,转换成新的key、value输出。 1.3 对输出的key、value进行分区。 1.4 对不同分区的数据,按照key进行排序、分组。相同key的value放到一个集合中。 1.5 (可选)分组后的数据进行归约。 2.reduce任务处理 2.1 对多个map任务的输出,按照不同的分区,通过网络copy到不同的reduce节点。 2.2 对多个map任务的输出进行合并、排序。写reduce函数自己的逻辑,对输入的key、value处理,转换成新的key、value输出。 2.3 把reduce的输出保存到文件中。 图2 word count的map和reduce过程示意图 MapReduce的基本设计思想 上面说了这么多,其实MapReduce的设计思想可以归结为如下三个: (1)对付大数据并行处理:分而治之 (2)上升到抽象模型:Map与Reduce (3)上升到构架:以统一构架为程序员隐藏系统层细节 *******************扩展********************* 同学:博主,怎么给萌妹子解释MapReduce呢?小讲:那就先来看看印度Java程序员Shekhar Gulati怎样向妻子解释MapReduce的吧(来源:CSDN) 我:你是如何准备洋葱辣椒酱的? 妻子: 我会取一个洋葱,把它切碎,然后拌入盐和水,最后放进混合研磨机里研磨。这样就能得到洋葱辣椒酱了。但这和MapReduce有什么关系? 我: 你等一下。让我来编一个完整的情节,这样你肯定可以在15分钟内弄懂MapReduce. 妻子: 好吧。 我:现在,假设你想用薄荷、洋葱、番茄、辣椒、大蒜弄一瓶混合辣椒酱。你会怎么做呢? 妻子: 我会取薄荷叶一撮,洋葱一个,番茄一个,辣椒一根,大蒜一根,切碎后加入适量的盐和水,再放入混合研磨机里研磨,这样你就可以得到一瓶混合辣椒酱了。 我:没错,让我们把MapReduce的概念应用到食谱上。Map和Reduce其实是两种操作,我来给你详细讲解下。Map(映射):把洋葱、番茄、辣椒和大蒜切碎,是各自作用在这些物体上的一个Map操作。所以你给Map一个洋葱,Map就会把洋葱切碎。 同样的,你把辣椒,大蒜和番茄一一地拿给Map,你也会得到各种碎块。 所以,当你在切像洋葱这样的蔬菜时,你执行就是一个Map操作。 Map操作适用于每一种蔬菜,它会相应地生产出一种或多种碎块,在我们的例子中生产的是蔬菜块。在Map操作中可能会出现有个洋葱坏掉了的情况,你只要把坏洋葱丢了就行了。所以,如果出现坏洋葱了,Map操作就会过滤掉坏洋葱而不会生产出任何的坏洋葱块。Reduce(化简):在这一阶段,你将各种蔬菜碎都放入研磨机里进行研磨,你就可以得到一瓶辣椒酱了。这意味要制成一瓶辣椒酱,你得研磨所有的原料。因此,研磨机通常将map操作的蔬菜碎聚集在了一起。 妻子: 所以,这就是MapReduce? 我: 你可以说是,也可以说不是。 其实这只是MapReduce的一部分,MapReduce的强大在于分布式计算。 妻子: 分布式计算? 那是什么?请给我解释下吧。 我: 没问题。 假设你参加了一个辣椒酱比赛并且你的食谱赢得了最佳辣椒酱奖。得奖之后,辣椒酱食谱大受欢迎,于是你想要开始出售自制品牌的辣椒酱。假设你每天需要生产10000瓶辣椒酱,你会怎么办呢? 妻子: 我会找一个能为我大量提供原料的供应商。 我:是的……就是那样的。那你能否独自完成制作呢?也就是说,独自将原料都切碎? 仅仅一部研磨机又是否能满足需要?而且现在,我们还需要供应不同种类的辣椒酱,像洋葱辣椒酱、青椒辣椒酱、番茄辣椒酱等等。 妻子: 当然不能了,我会雇佣更多的工人来切蔬菜。我还需要更多的研磨机,这样我就可以更快地生产辣椒酱了。 我:没错,所以现在你就不得不分配工作了,你将需要几个人一起切蔬菜。每个人都要处理满满一袋的蔬菜,而每一个人都相当于在执行一个简单的Map操作。每一个人都将不断的从袋子里拿出蔬菜来,并且每次只对一种蔬菜进行处理,也就是将它们切碎,直到袋子空了为止。 这样,当所有的工人都切完以后,工作台(每个人工作的地方)上就有了洋葱块、番茄块、和蒜蓉等等。 妻子:但是我怎么会制造出不同种类的番茄酱呢? 我:现在你会看到MapReduce遗漏的阶段---搅拌阶段。MapReduce将所有输出的蔬菜碎都搅拌在了一起,这些蔬菜碎都是在以key为基础的 map操作下产生的。搅拌将自动完成,你可以假设key是一种原料的名字,就像洋葱一样。 所以全部的洋葱keys都会搅拌在一起,并转移到研磨洋葱的研磨器里。这样,你就能得到洋葱辣椒酱了。同样地,所有的番茄也会被转移到标记着番茄的研磨器里,并制造出番茄辣椒酱。 本文转自大数据躺过的坑博客园博客,原文链接:http://www.cnblogs.com/zlslch/p/5077646.html,如需转载请自行联系原作者

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

[Android学习笔记四] 自定义Android组件之组合方式创建密码框组件

自定义Android组件基本可以从2个入口着手,一是继承Viewe类拿起画笔和画布绘制组件,而是通过继承View的子类和组合已有的组件的方式构造自定义的组件。 本文通过自定义一个PassWordView组件来实现密码能够通过点击点选框来决定是否显示。PassWordView组件类通过继承LinearLayout类和组合EditText,CheckBox组件实现。 效果如下图: 一: 实现上述密码框组件需要以下步骤: a. 设计PassWordView组件 b. 自定义样式属性,res/value/attrs.xml c. 创建PassWordView c. 实现PassWordView的功能,如:事件,属性设置,组合组件 二: 使用密码框组件: a. 使用PassWordView组件,设置属性 b. 在Activity中对其进行操作 三: 案例: 1. 密码框组件主要是组合EditText和CheckBox组件,通过CheckBox的选中状态来决定密码是否显示为明文,EditText和CheckBox组件要求并列一行。故采用LinearLayout布局。 2. 密码框组件的自定义样式属性,通常根据具体需要来定义。 PassWordView自定义组件中称EditText为left Component(左组件),CheckBox为right Component(右组件)。 定义样式属性(位置文件:res/value/attrs.xml): 1 2 3 4 5 6 7 8 9 10 < declare-styleable name = "PassWordView" > <!--直接使用系统中已定义的语意明确的属性,不用设置format--> < attr name = "android:inputType" /> <!--自定义属性--> < attr name = "left_component_weight" format = "float" /> < attr name = "right_component_weight" format = "float" /> </ declare-styleable > 其中inputType使用了android系统已经定义的属性,注意书写格式。 3. 实现PassWordView类 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 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 package secondriver.viewlibrary; import android.content.Context; import android.content.res.TypedArray; import android.text.InputType; import android.text.method.HideReturnsTransformationMethod; import android.text.method.PasswordTransformationMethod; import android.util.AttributeSet; import android.view.ViewGroup; import android.widget.CheckBox; import android.widget.CompoundButton; import android.widget.EditText; import android.widget.LinearLayout; /** *PassWordView *<p/> *leftComponent是一个EditText *RightComponent是一个CheckBox *<p/> *Author:secondriver *Created:2015/11/25 */ public class PassWordView extends LinearLayout{ private EditTextmPassWordEditText; private CheckBoxmShowCheckBox; private LinearLayout.LayoutParamsmPassWordParams; private LinearLayout.LayoutParamsmShowParams; private float leftComponentWeight; private float rightComponentWeight; private int inputType; public PassWordView(Contextcontext,AttributeSetattrs){ super (context,attrs); initProperty(context,attrs); initComponent(context); } private final void initProperty(Contextcontext,AttributeSetattrs){ //获取设置的值,未设置使用默认值 TypedArraytypedArray=context.obtainStyledAttributes(attrs,R.styleable.PassWordView); leftComponentWeight=typedArray.getFloat(R.styleable.PassWordView_left_component_weight, 5 .0f); rightComponentWeight=typedArray.getFloat(R.styleable.PassWordView_right_component_weight, 1 .0f); //来自Android系统已定义的属性 inputType=typedArray.getInt(R.styleable.PassWordView_android_inputType,InputType.TYPE_TEXT_VARIATION_PASSWORD); typedArray.recycle(); } private void initComponent(Contextcontext){ mPassWordEditText= new EditText(context); mPassWordEditText.setInputType(inputType); mPassWordEditText.setTransformationMethod(PasswordTransformationMethod.getInstance()); mShowCheckBox= new CheckBox(context); //通过权重来决定EditText和CheckBox占据父视图的空间的比例 mPassWordParams= new LinearLayout.LayoutParams( 0 ,ViewGroup.LayoutParams.WRAP_CONTENT,leftComponentWeight); mShowParams= new LinearLayout.LayoutParams( 0 ,ViewGroup.LayoutParams.WRAP_CONTENT,rightComponentWeight); //父视图是一个容器视图,指定水平排列子视图 setOrientation(HORIZONTAL); addView(mPassWordEditText,mPassWordParams); addView(mShowCheckBox,mShowParams); addCheckBoxListener(); } /** *获取PassWord * *@return */ public StringgetPassWord(){ return mPassWordEditText.getText().toString(); } /** *获取PassWord组件 * *@return */ public EditTextgetPassWordEditText(){ return mPassWordEditText; } private final void addCheckBoxListener(){ /** *CheckBox点击事件处理 * *如果选中EditText中的密码明文显示 * *如果未选中EditText中的密码黑点显示 * */ mShowCheckBox.setOnCheckedChangeListener( new CompoundButton.OnCheckedChangeListener(){ @Override public void onCheckedChanged(CompoundButtonbuttonView, boolean isChecked){ if (isChecked){ mPassWordEditText.setTransformationMethod(HideReturnsTransformationMethod.getInstance()); } else { mPassWordEditText.setTransformationMethod(PasswordTransformationMethod.getInstance()); } } }); } } 4. 使用PassWordView组件 文件:activity_combine_view.xml 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 <? xml version = "1.0" encoding = "utf-8" ?> < LinearLayout xmlns:android = "http://schemas.android.com/apk/res/android" xmlns:passwordview = "http://schemas.android.com/apk/res-auto" android:layout_width = "match_parent" android:layout_height = "match_parent" android:orientation = "vertical" > < secondriver.viewlibrary.PassWordView android:id = "@+id/password_view" android:layout_width = "300dp" android:layout_height = "wrap_content" android:layout_margin = "10dp" android:background = "#565354" android:inputType = "textPassword" android:padding = "10dp" passwordview:left_component_weight = "5.0" passwordview:right_component_weight = "1.0" /> < Button android:layout_width = "match_parent" android:layout_height = "wrap_content" android:onClick = "onShowPassWord" android:text = "获取密码" /> < TextView android:id = "@+id/password_text_view" android:layout_width = "match_parent" android:layout_height = "wrap_content" android:hint = "显示password" /> </ LinearLayout > 文件:CombinePassWordViewActivity.java 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 32 package secondriver.sdk.activity; import android.app.Activity; import android.os.Bundle; import android.view.View; import android.widget.TextView; import secondriver.sdk.R; import secondriver.viewlibrary.PassWordView; /** *Author:secondriver *Created:2015/11/25 */ public class CombinePassWordViewActivity extends Activity{ private PassWordViewmPassWordView; private TextViewmPassWordTextView; @Override protected void onCreate(BundlesavedInstanceState){ super .onCreate(savedInstanceState); setContentView(R.layout.activity_combine_view); mPassWordView=(PassWordView)findViewById(R.id.password_view); mPassWordTextView=(TextView)findViewById(R.id.password_text_view); } public void onShowPassWord(Viewview){ mPassWordTextView.setText(mPassWordView.getPassWord()); } } AndroidManifest.xml中添加CombinePassWordViewActivity即可。 5.结果 如文中一开始展示的效果图 6. 总结 本文主要演示的通过组合的方式实现自定义Android组件,一般情况通过组合已有的的组件来实现复杂组件相对更容易一些,也能够得到组件重用的福利;现有组件不能满足的情况下可以考虑绘制组件,该方式最为原始和灵活。 本文转自 secondriver 51CTO博客,原文链接:http://blog.51cto.com/aiilive/1716830,如需转载请自行联系原作者

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

Hadoop Hive概念学习系列之内部表和外部表对比分析(二)

Hive 的数据表分为两种,内部表和外部表。 内部表:这种表可以理解为数据和表结构都保存在一起的数据表。 外部表:在表结构创建以前,数据已经保存在 HDFS 中,通过创建表结构,将数据格式化到表的结果里。 进一步分析,内部表而言,当通过 DROP TABLE table_name 删除元数据中表结构的同时,表中的数据也同样会从 HDFS 中被删除。 外部表而言,当进行 DROP TABLE table_name 操作的时候,Hive 仅仅删除元数据的表结构,而不删除 HDFS 上的文件(即表里的数据),所以,相比内部表,外部表可以更放心大胆地使用。 数据表在删除的时候,内部表会连数据一起删除,而外部表只删除表结构,数据还是保留的。 本文转自大数据躺过的坑博客园博客,原文链接:http://www.cnblogs.com/zlslch/p/5660245.html,如需转载请自行联系原作者

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

Hadoop Hive概念学习系列之hive的正则表达式初步(六)

说在前面的话 hive的正则表达式,是非常重要!作为大数据开发人员,用好hive,正则表达式,是必须品! Hive中的正则表达式还是很强大的。数据工作者平时也离不开正则表达式。对此,特意做了个hive正则表达式的小结。所有代码都经过亲测,正常运行。 1.regexp 语法: A REGEXP B 操作类型: strings 描述: 功能与RLIKE相同 select count(*) from olap_b_dw_hotelorder_f where create_date_wid not regexp '\\d{8}' 与下面查询的效果是等效的: select count(*) from olap_b_dw_hotelorder_f where create_date_wid not rlike '\\d{8}'; 2.regexp_extract 语法: regexp_extract(string subject, string pattern, int index) 返回值: string 说明:将字符串subject按照pattern正则表达式的规则拆分,返回index指定的字符。 hive>selectregexp_extract('IloveYou','I(.*?)(You)',1) from test1 limit1; Total jobs =1 ... Total MapReduce CPU Time Spent:7 seconds340 msec OK love Time taken:28.067 seconds, Fetched:1 row(s) hive>selectregexp_extract('IloveYou','I(.*?)(You)',2) from test1 limit1; Total jobs =1 ... OK You Time taken:26.067 seconds, Fetched:1 row(s) hive>select regexp_extract('IloveYou','(I)(.*?)(You)',1) from test1 limit1; Total jobs =1 ... OK I Time taken:26.057 seconds, Fetched:1 row(s) hive>select regexp_extract('IloveYou','(I)(.*?)(You)',0) from test1 limit1; Total jobs =1 ... OK IloveYou Time taken:28.06 seconds, Fetched:1 row(s) hive>select regexp_replace("IloveYou","You","") from test1 limit1; Total jobs =1 ... OK Ilove Time taken:26.063 seconds, Fetched:1 row(s) 3.regexp_replace 语法: regexp_replace(string A, string B, string C) 返回值: string 说明:将字符串A中的符合Java正则表达式B的部分替换为C。注意,在有些情况下要使用转义字符,类似Oracle中的regexp_replace函数。 hive> selectregexp_replace("IloveYou","You","") from test1 limit1; Total jobs =1 ... OK Ilove Time taken:26.063 seconds, Fetched:1 row(s) hive>selectregexp_replace("IloveYou","You","lili") from test1 limit1; Total jobs =1 ... OK Ilovelili Hive里的正则表达式 如,https://cwiki.apache.org/confluence/display/Hive/GettingStarted 输入regex可查到 CREATE TABLE apachelog ( host STRING, identity STRING, user STRING, time STRING, request STRING, status STRING, size STRING, referer STRING, agent STRING) ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.RegexSerDe' WITH SERDEPROPERTIES ("input.regex" = "([^ ]*) ([^ ]*) ([^]*) \[()\] ([^ \"]*|\"[^\"]*\") (-|[0-9]*) (-|[0-9]*)(?: ([^ \"]*|\".*\") ([^ \"]*|\".*\"))?" ) STORED AS TEXTFILE; 下面就是hive里的正则表达式,9个字段,对应定义那边也要9个 "input.regex" = "([^ ]*) ([^ ]*) ([^.]*) \[(.*)\] "(.*)" (-|[0-9]*) (-|[(0-9]*) "(.*)" "(.*)"" ([^ ]*) ([^ ]*) ([^.]*) \[(.*)\] "(.*)" (-|[0-9]*) (-|[(0-9]*) "(.*)" "(.*)" ([^ ]*) ([^ ]*) ([^.]*) \\[(.*)\\] "(.*)" (-|[0-9]*) (-|[(0-9]*) \"(.*)\" \"(.*)\" 数据来源, yarn-root-nodemanager-master.log 或 yarn-spark-nodemanager-master.log yarn-hadoop-nodemanager-master.log 这里,有个正则表达式的好工具! RegexBuddy.exe 很好用的这款软件!双击它即可。 如上图所示颜色,代表我们测试的正则表达式,是正确的! 本文转自大数据躺过的坑博客园博客,原文链接:http://www.cnblogs.com/zlslch/p/6102789.html,如需转载请自行联系原作者

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

Spark 概念学习系列之Apache Spark 架构详解(十)(必须好好理解悟透)

Spark的架构图如下: 分别解释 1、Driver:运行 Application 的 main() 函数并且创建 SparkContext。 2、Client:用户提交作业的客户端。(类似于Hadoop里的Client) 3、Worker:集群中任何可以运行 Application 代码的节点,运行一个或多个 Executor进程。 4、Executor :运行在 Worker 的 Task 执行器, Executor 启动线程池运行 Task,并且负责将数据存在内存或者磁盘上。每个 Application 都会申请各自的 Executor 来处理任务。(类似于Hadoop里的NodeManager) 5、SparkContext:整个应用的上下文,控制应用的生命周期。(类似于Hadoop里的Context上下文) 6、RDD: Spark 的基本计算单元,一组 RDD 形成执行的有向无环图 RDD Graph。 7、DAG Scheduler:根据 Job 构建基于 Stage 的 DAG 工作流,并提交 Stage 给TaskScheduler。 8、TaskScheduler:将 Task 分发给 Executor 执行。 9、SparkEnv:线程级别的上下文,存储运行时的重要组件的引用。 本文转自大数据躺过的坑博客园博客,原文链接:http://www.cnblogs.com/zlslch/p/5718842.html,如需转载请自行联系原作者

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

Hadoop HDFS概念学习系列之初步掌握HDFS的架构及原理1(一)

HDFS 是做什么的? HDFS(Hadoop Distributed File System)是Hadoop项目的核心子项目,是分布式计算中数据存储管理的基础,是基于流数据模式访问和处理超大文件的需求而开发的,可以运行于廉价的商用服务器上。它所具有的高容错、高可靠性、高可扩展性、高获得性、高吞吐率等特征为海量数据提供了不怕故障的存储,为超大数据集(Large Data Set)的应用处理带来了很多便利。 HDFS 从何而来? HDFS 源于 Google 在2003年10月份发表的GFS(Google File System)论文。它其实就是 GFS 的一个克隆版本。 为什么选择 HDFS 存储数据? 之所以选择 HDFS 存储数据,因为 HDFS 具有以下优点: 1、高容错性 1)数据自动保存多个副本。它通过增加副本的形式,提高容错性。 2)某一个副本丢失以后,它可以自动恢复,这是由 HDFS 内部机制实现的,我们不必关心。 2、适合批处理 1)它是通过移动计算而不是移动数据。 2)它会把数据位置暴露给计算框架。 3、适合大数据处理 1)处理数据达到 GB、TB、甚至PB级别的数据。 2)能够处理百万规模以上的文件数量,数量相当之大。 3)能够处理10K节点的规模。 4、流式文件访问 1)一次写入,多次读取。文件一旦写入不能修改,只能追加。 2)它能保证数据的一致性。 5、可构建在廉价机器上 1)它通过多副本机制,提高可靠性。 2)它提供了容错和恢复机制。比如某一个副本丢失,可以通过其它副本来恢复。 当然 HDFS 也有它的劣势,并不适合所有的场合: 1、低延时数据访问 1)比如毫秒级的来存储数据,这是不行的,它做不到。 2)它适合高吞吐率的场景,就是在某一时间内写入大量的数据。但是它在低延时的情况下是不行的,比如毫秒级以内读取数据,这样它是很难做到的。 2、小文件存储 1)存储大量小文件的话,它会占用 NameNode大量的内存来存储文件、目录和块信息。这样是不可取的,因为NameNode的内存总是有限的。 2)小文件存储的寻道时间会超过读取时间,它违反了HDFS的设计目标。 (这里的小文件是指小于HDFS系统的Block大小的文件,默认是64M) 3、并发写入、文件随机修改 1)一个文件只能有一个写,不允许多个线程同时写。 2)仅支持数据 append(追加),不支持文件的随机修改。 HDFS 如何存储数据? HDFS 采用Master/Slave的架构来存储数据,这种架构主要由四个部分组成,分别为HDFS Client、NameNode、DataNode和Secondary NameNode。下面我们分别介绍这四个组成部分。 Client:就是客户端。 1、文件切分。文件上传 HDFS 的时候,Client 将文件切分成 一个一个的Block,然后进行存储。 2、与 NameNode 交互,获取文件的位置信息。 3、与 DataNode 交互,读取或者写入数据。 4、Client 提供一些命令来管理 HDFS,比如启动或者关闭HDFS。 5、Client 可以通过一些命令来访问 HDFS。 NameNode:就是 master,它是一个主管、管理者。 1、管理 HDFS的名称空间。 2、管理数据块(Block)映射信息 3、配置副本策略 4、处理客户端读写请求。 数据块 1)HDFS默认的最基本的存储单位是128M的数据块。 2)和普通文件系统相同的是,HDFS中的文件是被分成为每块为128M的数据块进行存储的。 3)不同于普通文件系统的是,HDFS中,如果一个文件小于一个数据块的大小,并不占用整个数据块存储空间。 副本策略 比如,一个10M的数据文件,进来被切分很多个Block,每个Block都有3个副本 HDFS中的数据块(Block)会有多个副本,默认为3个,当然这个副本也是可以配置的。为了数据安全和高效,Hadoop默认对3个副本的存放策略如下: 第一块:在本地机器的HDFS目录下存储一个Block. 第二块:不同Rack(机器)的某个DataNode上存储一个Block. 第三块:在该机器的同一个Rack下的某台机器上存储最后一个Block. 其他副本:还存在其它副本就随机挑选存储位置。 DataNode:就是Slave。NameNode 下达命令,DataNode 执行实际的操作。 1、存储实际的数据块。 2、执行数据块的读/写操作。 Secondary NameNode:并非NameNode 的热备(热备从广义上讲,就是服务器高可用应用的另一种说法,从狭义上讲,双机热备特指基于高可用系统中的两台服务器的热备)。当NameNode 挂掉的时候,它并不能马上替换 NameNode 并提供服务。 1、辅助 NameNode,分担其工作量。 2、定期合并fsimage和fsedits,并推送给NameNode。 3、在紧急情况下,可辅助恢复 NameNode。 fsimage与edits是NameNode的两个重要文件。 1)fsimage:元数据镜像文件(文件系统的目录树,比如说有哪些目录,每个目录有哪些文件,这些信息都保存在fsimage文件中。) 2)edits:元数据操作日志(针对目录树的修改操作,比如你删除了某个文件或者增加了某个文件,它都会把这些操作保存在edits中。) 本文转自大数据躺过的坑博客园博客,原文链接:http://www.cnblogs.com/zlslch/p/5080092.html,如需转载请自行联系原作者

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

Hadoop HDFS概念学习系列之初步掌握HDFS的架构及原理3(三)

HDFS 如何写入文件? HDFS的文件写入原理,主要包括以下几个步骤: 1.客户端通过调用DistributedFileSystem的create方法,创建一个新的文件。 2.DistributedFileSystem通过RPC(远程过程调用)调用NameNode,去创建一个没有blocks关联的新文件。创建前,NameNode 会做各种校验,比如文件是否存在,客户端有无权限去创建等。如果校验通过,NameNode就会记录下新文件,否则就会抛出IO异常。 3.前两步结束后会返回 FSDataOutputStream 的对象,和读文件的时候相似,FSDataOutputStream 被封装成 DFSOutputStream,DFSOutputStream 可以协调 NameNode和 DataNode。客户端开始写数据到DFSOutputStream,DFSOutputStream会把数据切成一个个小packet,然后排成队列 data queue。 4.DataStreamer 会去处理接受 data queue,它先问询 NameNode 这个新的 block 最适合存储的在哪几个DataNode里,比如重复数是3,那么就找到3个最适合的 DataNode,把它们排成一个 pipeline。DataStreamer 把 packet 按队列输出到管道的第一个 DataNode 中,第一个 DataNode又把 packet 输出到第二个 DataNode 中,以此类推。 5.DFSOutputStream 还有一个队列叫 ack queue,也是由 packet 组成,等待DataNode的收到响应,当pipeline中的所有DataNode都表示已经收到的时候,这时akc queue才会把对应的packet包移除掉。 6.客户端完成写数据后,调用close方法关闭写入流。 7.DataStreamer 把剩余的包都刷到 pipeline 里,然后等待 ack 信息,收到最后一个 ack 后,通知 DataNode 把文件标示为已完成。 第一,客户端通过调用DistributedFileSystem对象中的creat()函数创建一个文件,DistributedFileSystem通过RPC调用在NameNode的文件系统命名空间中创建一个新文件,此时还没有相关的DataNode与之关联。 第二,NameNode会通过多种验证保证新的文件不存在于文件系统中,并且确保请求客户端拥有创建文件的权限。当所有验证通过时,NameNode会创建一个新文件的记录,如果创建失败,则抛出一个IOExceptinn异常;如果成功,则DistrihutedFiieSystem返回一个FSDataOutputStream给客户端用来写入数据。这里FSDataOutputStream和读取数据时的FSDataInputStream一样都包含一个数据流对象DFSOutputStream,客户端将使用它来处理与DataNode和NameNode之间的通信。第三,当客户端写入数据时,DFSOutputStream会将文件分割成包,然后放入一个内部队列,我们称为“数据队列”。DataStreamer会将这些小的文件包放入数据流中,DataStreamer的作用是请求NameNode为新的文件包分配合适的DataNade存放副本。返回的DataNode列表形成一个“管道”,假设这里的副本数是3,那么这个管道中就会有3个DataNode, DataStreamer将文件包以流的方式传送给队列中的第一个DataNode。第一个DataNDode会存储这个包,然后将它推送到第二个DataNode中,随后照这样进行,直到管道中的最后一个DataNode。 第四,DFSOutputStream同时也会保存一个包的内部队列,用来等待管道中的DataNode返回确认信息,这个队列被称为确认队列〔ack queue)。只有当所有管道中的DataNode都返回了写入成功的返回信息文件包,才会从确认队列中删除。 当然,HDFS会考虑写入失败的情况,当数据写入节点失败时,HDFS会做出以下反应。首先管道会被关闭,任何在确认通知队列中的文件包都会被添加到数据队列的前端,这样管道中失败的DataNode都不会丢失数据。当前存放在正常工作的DataNode之上的文件块会被赋予一个新的身份,井且和NameNode进行关联,这样,如果失败的DataNode过段时间后会从故障中恢复出来。其中的部分数据块就会被删除。然后,管道会把失败的DataNode删除,文件会继续被写到管道中的另外两个DataNode中。最后,NameNode会注意到现在的文件块副本数没有达到配置属性要求,会在另外的DataNode上重新安排创建一个副本,随后的文件会正常执行写入操作。 当然,在文件块写入期间,多个DataNode同时出现故障的可能性存在,但是很小。只要dfs.replicatinn.min的属性值(默认为1)成功写入,这个文件块就会被异步复制到集群的其他 DataNode中,直到满足dfs. rcplication. min的属性值(默认为3)。 客户端成功完成数据写入的操作后,就会调用6种close()函数关闭数据流。这步操作会在连接NameNode确认文件写入完全之前将所有剩下的文件包放入DataNode管道,等待通知确认信息.NameNode会知道哪些块组成一个文件(通过DataStreamer获得块位置信息),这样NameNode只要在返回成功标志前等待块被最小量(dfs.replication.min )复制即可。 本文转自大数据躺过的坑博客园博客,原文链接:http://www.cnblogs.com/zlslch/p/5080350.html,如需转载请自行联系原作者

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

[Android学习笔记八] 使用VideoView屏幕方向发生变化,视频方向自动切换

一个Activity主要用来做播放视频使用,并且是全屏播放的话,主要采用横屏(Landscape orientation 显示宽度大于高度)显示视频,那么可以指定Activity的属性android:screenOrientation="landscape"让Activity在设备上以横屏显示。 本文使用VideoView来显示视屏,Potrait(竖屏)时布局样式中宽匹配父布局,高匹配内容;Landscape(横屏)时布局样式中宽匹配内容,高匹配布局。视屏播放中,用户调正设备方向时,导致屏幕方向发生变化,视屏能够适应布局样式显示视频,并正常继续播放。 示例图: 1. 构建布局 Potrait: res/layout/activity_videoview.xml 1 2 3 4 5 6 7 8 9 10 11 <? xml version = "1.0" encoding = "utf-8" ?> < LinearLayout xmlns:android = "http://schemas.android.com/apk/res/android" android:layout_width = "match_parent" android:layout_height = "match_parent" android:orientation = "vertical" > < VideoView android:id = "@+id/videoView" android:layout_width = "match_parent" android:layout_height = "wrap_content" android:layout_gravity = "center_horizontal" android:layout_margin = "5dp" /> </ LinearLayout > Landscape: res/layout-land/activity_videoview.xml 1 2 3 4 5 6 7 8 9 10 <? xml version = "1.0" encoding = "utf-8" ?> < LinearLayout xmlns:android = "http://schemas.android.com/apk/res/android" android:orientation = "vertical" android:layout_width = "match_parent" android:layout_height = "match_parent" > < VideoView android:layout_width = "wrap_content" android:layout_height = "match_parent" android:id = "@+id/videoView" android:layout_gravity = "center_horizontal" android:layout_margin = "5dp" /> </ LinearLayout > 2.创建Activity 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 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 package secondriver.sdk.activity; import android.app.Activity; import android.app.ProgressDialog; import android.content.res.Configuration; import android.media.MediaPlayer; import android.net.Uri; import android.os.Bundle; import android.util.Log; import android.widget.MediaController; import android.widget.Toast; import android.widget.VideoView; import secondriver.sdk.R; /** *Author:secondriver *Created:2015/11/30 */ public class VideoViewActivity extends Activity implements MediaPlayer.OnPreparedListener,MediaPlayer.OnCompletionListener,MediaPlayer.OnErrorListener{ private final StringTAG=VideoViewActivity. class .getName(); public VideoViewvideoView; public MediaControllermediaController; public int videoPosition= 0 ; public ProgressDialogdialog; @Override protected void onCreate(BundlesavedInstanceState){ Log.d(TAG, "onCreate" ); super .onCreate(savedInstanceState); setContentView(R.layout.activity_videoview); dialog= new ProgressDialog( this ); dialog.setTitle( "视屏播放器" ); dialog.setMessage( "正在加载..." ); dialog.setCancelable( false ); mediaController= new MediaController( this ); videoView=(VideoView)findViewById(R.id.videoView); videoView.setMediaController(mediaController); videoView.setOnCompletionListener( this ); videoView.setOnPreparedListener( this ); videoView.setOnErrorListener( this ); } private void loadVideo(){ Log.d(TAG, "loadvideo" ); dialog.show(); try { videoView.setVideoURI(Uri.parse( "android.resource://" +getPackageName()+ "/" +R.raw.bsg)); } catch (Exceptione){ Log.e(TAG,e.getMessage()); } } @Override protected void onStart(){ Log.d(TAG, "onStart" ); super .onStart(); loadVideo(); } @Override public void onConfigurationChanged(ConfigurationnewConfig){ Log.d(TAG, "onConfigurationChanged" ); super .onConfigurationChanged(newConfig); } @Override public void onCompletion(MediaPlayermp){ Log.d(TAG, "MediaonCompletion" ); Toast.makeText(VideoViewActivity. this , "播放完成" ,Toast.LENGTH_LONG).show(); mp.release(); } @Override public void onPrepared(MediaPlayermp){ Log.d(TAG, "MediaonPrepared" ); if (dialog.isShowing()){ dialog.dismiss(); } mp.seekTo(videoPosition); if (videoPosition== 0 ){ mp.start(); } else { mp.pause(); } } @Override public boolean onError(MediaPlayermp, int what, int extra){ Log.d(TAG, "MediaonError" ); Stringerr= "未知错误" ; switch (what){ case MediaPlayer.MEDIA_ERROR_UNKNOWN: break ; case MediaPlayer.MEDIA_ERROR_SERVER_DIED: err= "媒体服务终止" ; break ; default : break ; } Toast.makeText(VideoViewActivity. this ,err,Toast.LENGTH_LONG).show(); return true ; } } 3. 设置Activity属性 1 2 3 <activityandroid:name= ".activity.VideoViewActivity" android:configChanges= "orientation|screenSize|keyboardHidden" /> 代码中重写了onConfigurationChanged,可以在此处做配置发生变化的处理。 在运行时发生配置更改,Activity被关闭,默认情况下重新启动,但在设置了Activity的configChanges属性的配置将防止活动被重新启动,Activity仍在运行并且onConfigurationChanged方法被调用。 需要注意的是如果应用程序的target API level是13+的话(声明了minSdkversion和targetSdkVersion属性),需要同时设置screensize, 因为设备的横竖方向发生变化的时候,当前屏幕的可用尺寸也将发生变化。 本文转自 secondriver 51CTO博客,原文链接:http://blog.51cto.com/aiilive/1718653,如需转载请自行联系原作者

资源下载

更多资源
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应用均可从中受益。

用户登录
用户注册