-
Notifications
You must be signed in to change notification settings - Fork 0
/
search.xml
2975 lines (2619 loc) · 388 KB
/
search.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
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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<?xml version="1.0" encoding="utf-8"?>
<search>
<entry>
<title>gitBasic</title>
<url>/2020/06/03/gitBasic/</url>
<content><![CDATA[<h1 id="0x00-git的配置"><a href="#0x00-git的配置" class="headerlink" title="0x00 git的配置"></a>0x00 git的配置</h1><a id="more"></a>
<h2 id="设置姓名和邮箱地址"><a href="#设置姓名和邮箱地址" class="headerlink" title="设置姓名和邮箱地址"></a>设置姓名和邮箱地址</h2><figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">$ git config --global user.name "Firstname Lastname"</span><br><span class="line">$ git config --global user.email "[email protected]"</span><br></pre></td></tr></table></figure>
<p>这个命令,会在“~/.gitconfig”中以输出设置文件,可以直接编辑它</p>
<h2 id="设置代理"><a href="#设置代理" class="headerlink" title="设置代理"></a>设置代理</h2><p><a href="https://gist.github.com/laispace/666dd7b27e9116faece6" target="_blank" rel="noopener">https://gist.github.com/laispace/666dd7b27e9116faece6</a><br>这里需要看自己设置的代理是哪一个端口</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">git config --global http.proxy 'socks5://127.0.0.1:1080'</span><br><span class="line">git config --global https.proxy 'socks5://127.0.0.1:1080'</span><br></pre></td></tr></table></figure>
<p>或则是http代理</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">git config --global https.proxy http://127.0.0.1:1080</span><br><span class="line">git config --global https.proxy https://127.0.0.1:1080</span><br></pre></td></tr></table></figure>
<p>设置取消代理</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">git config --global --unset http.proxy</span><br><span class="line">git config --global --unset https.proxy</span><br></pre></td></tr></table></figure>
]]></content>
<categories>
<category>linux</category>
</categories>
<tags>
<tag>git</tag>
</tags>
</entry>
<entry>
<title>redis-basic</title>
<url>/2020/03/07/redis-basic/</url>
<content><![CDATA[<p>Redis学习记录<br>版本:Redis-2.8.0.tar.gz<br>下载链接:<a href="http://download.redis.io/releases/" target="_blank" rel="noopener">http://download.redis.io/releases/</a></p>
<a id="more"></a>
<h1 id="0x00-Redis导论"><a href="#0x00-Redis导论" class="headerlink" title="0x00 Redis导论"></a>0x00 Redis导论</h1><h2 id="简介"><a href="#简介" class="headerlink" title="简介"></a>简介</h2><p>Redis:REmote DIctionary Server<br>字面意思:远程字典服务</p>
<ul>
<li>Redis是一个使用<code>ANSI C</code>语言编写的开源数据库</li>
<li>高性能的<code>key-value</code>数据库</li>
<li>内存数据库,支持数据持久化</li>
</ul>
<p>官网:<a href="https://redis.io/" target="_blank" rel="noopener">https://redis.io/</a><br>国内官网:<a href="http://redis.cn/" target="_blank" rel="noopener">http://redis.cn/</a></p>
<h2 id="安装"><a href="#安装" class="headerlink" title="安装"></a>安装</h2><p>直接下载解压即<br>然后在解压后的目录输入<code>make</code><br>之后进入<code>src</code>目录下<br>启动redis:<code>./redis-server</code><br><code>./redis-server &</code>后台启动。<br>关闭redis:<code>./redis-cli shutdown</code></p>
<h2 id="使用自带客户端"><a href="#使用自带客户端" class="headerlink" title="使用自带客户端"></a>使用自带客户端</h2><p>src目录下运行<code>./redis-cli</code></p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">set a b</span><br><span class="line">set b c</span><br><span class="line">key *</span><br><span class="line">get a</span><br><span class="line">get b</span><br></pre></td></tr></table></figure>
<h2 id="数据类型"><a href="#数据类型" class="headerlink" title="数据类型"></a>数据类型</h2><ul>
<li>string</li>
<li>list</li>
<li>set</li>
<li>sorted set</li>
<li>hash</li>
</ul>
<h1 id="0x01-redis服务启动的方式"><a href="#0x01-redis服务启动的方式" class="headerlink" title="0x01 redis服务启动的方式"></a>0x01 redis服务启动的方式</h1><h2 id="直接启动"><a href="#直接启动" class="headerlink" title="直接启动"></a>直接启动</h2><p>src目录下运行<code>./redis-server</code><br>新开一个命令窗口运行<code>./redis-cli</code></p>
<blockquote>
<p>直接用<code>ctrl+c</code>关闭客户端时不会持久化的,可以运行<code>save</code>命令持久化。一个比较好的命令是<code>./redis-cli shutdown</code></p>
</blockquote>
<h2 id="指定端口启动"><a href="#指定端口启动" class="headerlink" title="指定端口启动"></a>指定端口启动</h2><p>默认端口是6379。<br><code>./redis-server --port 6380</code><br>那么运行客户端时的命令:<code>./redis-cli -p 6380</code><br>关闭客户端时命令:<code>./redis-cli -p 6380 shutdown</code></p>
<h2 id="修改配置文件启动"><a href="#修改配置文件启动" class="headerlink" title="修改配置文件启动"></a>修改配置文件启动</h2><p>修改主目录下的<code>redis.conf</code><br>找到port这个节点,修改它的值<br><img src="/images/redis/p1.png" alt="pic"><br>再次进入src目录下<br>指定配置文件运行<br><code>./redis-server ../redis.conf</code><br>有时候需要指定IP关闭(默认时localhost):<code>./redis-cli -p 6379 -h 127.0.0.1</code></p>
<h2 id="配置密码"><a href="#配置密码" class="headerlink" title="配置密码"></a>配置密码</h2><p>修改主目录下的<code>redis.conf</code><br>搜索<code>\requirepass</code>,定位到这一行, 将注释去掉,添加密码值<br>以配置文件启动<br><code>./redis-server ../redis.conf</code><br>这个时候需要用密码启动客户端<br><code>./redis-cli -a yijun</code></p>
<h1 id="0x02-系统级命令"><a href="#0x02-系统级命令" class="headerlink" title="0x02 系统级命令"></a>0x02 系统级命令</h1><h2 id="info"><a href="#info" class="headerlink" title="info"></a>info</h2><p>查看系统信息,如服务进程ID,端口,版本,客户端,内存,状态,主从同步数据,CPU,Keyspace(命名空间)</p>
<h2 id="Keyspace"><a href="#Keyspace" class="headerlink" title="Keyspace"></a>Keyspace</h2><p><img src="/images/redis/p2.png" alt="pic"><br>可以看到默认的db空间时db0,此时有2个key存储在这个数据库<br>可以通过<code>select <dbid></code>选择运用的数据库/命名空间,下标从0开始<br>如进入客户端<code>./redis-cli</code><br>运行<code>selcet 1</code>选择db1运行</p>
<h2 id="flushdb"><a href="#flushdb" class="headerlink" title="flushdb"></a>flushdb</h2><p>清空当前db下的所有key值</p>
<h2 id="flushall"><a href="#flushall" class="headerlink" title="flushall"></a>flushall</h2><p>清空所有db信息</p>
<h2 id="dbsize"><a href="#dbsize" class="headerlink" title="dbsize"></a>dbsize</h2><p>当前db下的key-value数量</p>
<h1 id="0x03-Redis键命令"><a href="#0x03-Redis键命令" class="headerlink" title="0x03 Redis键命令"></a>0x03 Redis键命令</h1><h2 id="新增健"><a href="#新增健" class="headerlink" title="新增健"></a>新增健</h2><p><code>set key value</code>设置一个值<br><code>keys *</code><br><code>mset k1 v1 k2 v2</code>同时设置多个key-value<br><code>setnx key value</code>只有key不存在时才成功</p>
<h2 id="删除键"><a href="#删除键" class="headerlink" title="删除键"></a>删除键</h2><p><code>del key</code><br>存在就删除返回1,不存在返回0</p>
<h2 id="取值"><a href="#取值" class="headerlink" title="取值"></a>取值</h2><p><code>get key</code><br><code>getset key newValue</code><br>拿到一个旧值,并且会设置新值<br><code>mget k1 k2 k3</code>批量拿值</p>
<h2 id="判断是否存在"><a href="#判断是否存在" class="headerlink" title="判断是否存在"></a>判断是否存在</h2><p><code>exists key</code><br>存在返回1,否则返回0</p>
<h2 id="查看key剩余时间"><a href="#查看key剩余时间" class="headerlink" title="查看key剩余时间"></a>查看key剩余时间</h2><p><code>ttl key</code><br>返回-1表示永久有效<br>不存在的key返回-2</p>
<h2 id="设置键的有效期"><a href="#设置键的有效期" class="headerlink" title="设置键的有效期"></a>设置键的有效期</h2><p><code>expire key time</code><br>这里的time是一个整数,单位为秒<code>expire key 10</code><br><code>setex key time value</code><br>加入一个键,设置有效期<br><code>psetex key tim value</code><br>时间为毫秒</p>
<h2 id="查看key对应值的类型"><a href="#查看key对应值的类型" class="headerlink" title="查看key对应值的类型"></a>查看key对应值的类型</h2><p><code>type key</code></p>
<h2 id="随机key"><a href="#随机key" class="headerlink" title="随机key"></a>随机key</h2><p><code>randomkey</code>从已有的key中随机取出</p>
<h2 id="key重命名"><a href="#key重命名" class="headerlink" title="key重命名"></a>key重命名</h2><p><code>rename oldKey newKey</code><br>会覆盖已经存在的key<br><code>renamenx oldKey newKey</code><br>会进行判断,已经存在的话就不判断</p>
<h1 id="0x04-Redis数据结构"><a href="#0x04-Redis数据结构" class="headerlink" title="0x04 Redis数据结构"></a>0x04 Redis数据结构</h1><h2 id="string"><a href="#string" class="headerlink" title="string"></a>string</h2><p><code>strlen key</code> 得到key对应值的字符串长度<br><code>append key value</code> 将key对应的值后面拼接value对应的字符串</p>
<h2 id="hash"><a href="#hash" class="headerlink" title="hash"></a>hash</h2><ul>
<li><code>hset key itemKey itemValue</code><br>设置一个key,它的值是一个hash数据结构<br>可以知道类型<code>type key</code></li>
<li><code>hexists key itemKey</code><br>键key对应的值是否有itemKey字段</li>
<li><code>hget key itemKey</code><br>取得key对应的itemkey对应的值</li>
<li><code>hgetall key</code><br>得到key对应的的value值</li>
<li><code>hkeys key</code><br>得到key对应值所有key键</li>
<li><code>hvals key</code><br>得到key对应值的所有value</li>
<li><code>hlen key</code><br>得到key对应值value大小</li>
<li><code>hkeys key itemKey1 itemKey2</code><br>删除keyItem</li>
</ul>
<h2 id="list"><a href="#list" class="headerlink" title="list"></a>list</h2><ul>
<li><code>lpush key v1 v2 v3 v4</code><br>将列表值存放到key</li>
<li><code>llen key</code><br>得到list的长度</li>
<li><code>lrange key 0 2</code><br>取得list中的[0, 2]下标的值,与push进的值相反</li>
<li><code>lset key 0 value</code><br>设置list下标为0的值</li>
<li><code>lindex key 5</code><br>获取list的第五号元素</li>
<li><code>lpop key</code><br>移除第一个元素</li>
<li><code>rpop key</code><br>移除最后一个</li>
</ul>
<h2 id="set"><a href="#set" class="headerlink" title="set"></a>set</h2><p>无序集合,可以排除重复</p>
<ul>
<li><code>sadd key v1 v2 v3 v4</code><br>新建一个key,value是set的元素,set集是v1,v2,v3,v4</li>
<li><code>scard key</code><br>返回集合value的大小</li>
<li><code>rename oldKey newKey</code><br>改名</li>
<li><code>smembers key</code><br>查看集合的所有元素成员</li>
<li><code>sdiff key1 key2</code><br>key1中的元素减去两者共有的元素得到的集合</li>
<li><code>sinter key1 key2</code><br>两个集合的交集</li>
<li><code>sunion key1 key2</code><br>两个集合的并集</li>
<li>返回一个或者集合中的随机数个数<br><code>srandmember key 3</code>,返回key中的3个随机成员</li>
<li><code>sismember key value</code><br>判断value是不是集合key里面的元素</li>
<li><code>srem key v1 v2</code><br>移除集合key中的元素v1,v2</li>
<li><code>spop key</code><br>移除key集合中的一个随机元素,并且返回它的值</li>
</ul>
<h2 id="sortedSet"><a href="#sortedSet" class="headerlink" title="sortedSet"></a>sortedSet</h2><p>有序集合,通过分数来进行排序</p>
<ul>
<li><code>zadd key 100 a 200 b 300 c</code><br>创建三个值,其分数分别是100,200,300</li>
<li><code>zcard key</code><br>查看有序集合key的元素个数</li>
<li><code>zscore key valueItem</code><br>查看集合key中的某一个值的分数</li>
<li><code>zcount key 0 220</code><br>返回[0, 220]的分数对应的值的个数</li>
<li><code>zrank key valueitem</code><br>返回指定元素对应的索引</li>
<li><code>zincrby key 1000 a</code><br>将key集合中对应的元素a的分数加1000分</li>
<li><code>zrange key 0 100</code><br>查看集合key中分数区间[0,100]中的所有value</li>
<li><code>zrange key 0 100 withscores</code><br>查看集合key中分数区间[0,100]中的所有value及其分数</li>
</ul>
]]></content>
<categories>
<category>linux</category>
</categories>
<tags>
<tag>redis</tag>
</tags>
</entry>
<entry>
<title>mysql-basic</title>
<url>/2020/02/13/mysql-basic/</url>
<content><![CDATA[<p>mysql安装和使用<br>版本:ubuntu16.04与mysql-server-5.7</p>
<a id="more"></a>
<p><a href="http://dblab.xmu.edu.cn/blog/install-mysql/" target="_blank" rel="noopener">安装教程</a><br>root账户密码(Qwertyuiop123)</p>
<h1 id="0x00-字符集配置"><a href="#0x00-字符集配置" class="headerlink" title="0x00 字符集配置"></a>0x00 字符集配置</h1><p>编辑<code>sudo vim /etc/mysql/mysql.conf.d/mysqld.cnf</code><br>在[mysqlId]节点下添加如下内容</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">character_set_server=utf8</span><br></pre></td></tr></table></figure>
<h1 id="0x01-自启动配置"><a href="#0x01-自启动配置" class="headerlink" title="0x01 自启动配置"></a>0x01 自启动配置</h1><ol>
<li>执行<code>chkconfig mysqld on</code></li>
<li>执行<code>chkconfig --list mysqld</code>(查看2-5位启用on状态即可)</li>
</ol>
<h1 id="0x02-一些配置"><a href="#0x02-一些配置" class="headerlink" title="0x02 一些配置"></a>0x02 一些配置</h1><ul>
<li><p>服务启动:<code>service mysqld start</code></p>
</li>
<li><p>root用户登陆:<code>mysql -u root -p</code><br>登陆之后可以进行的操作。</p>
</li>
<li><p>查看mysql的用户:</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">select user,host,authentication_string from mysql.user</span><br></pre></td></tr></table></figure>
</li>
<li><p>修改root密码</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">set authentication_string for root@localhost=password('yourPassword')</span><br><span class="line">#或者</span><br><span class="line">set authentication_string for [email protected]=password('yourPassword')</span><br></pre></td></tr></table></figure>
</li>
<li><p>删除匿名用户</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">#查看是否有匿名用户</span><br><span class="line">select user,host from mysql.user;</span><br><span class="line">#删除匿名用户</span><br><span class="line">delete from mysql.user where user='';</span><br><span class="line">#刷新,生效</span><br><span class="line">flush privileges;</span><br></pre></td></tr></table></figure>
</li>
<li><p>插入新用户</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">CREATE USER 'test'@'localhost' IDENTIFIED BY '1234'; #本地登录 </span><br><span class="line">CREATE USER 'test'@'%' IDENTIFIED BY '1234'; #远程登录</span><br><span class="line">#使操作生效</span><br><span class="line">flush privileges;</span><br></pre></td></tr></table></figure>
</li>
<li><p>创建新的数据库</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">CREATE DATABASE mall DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;</span><br></pre></td></tr></table></figure>
</li>
<li><p>给某一个用户赋予某数据库的所有权限</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">grant all privileges on mall.* to youUsername@localhost identified by 'yourPassword'</span><br></pre></td></tr></table></figure>
</li>
<li><p>给某一个账户开通外网所有权限</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">grant all privileges on mall.* to youUsername@'%' identified by 'yourPassword'</span><br></pre></td></tr></table></figure>
</li>
</ul>
<blockquote>
<p>注意%号代表所有的IP地址,可以指定IP地址</p>
</blockquote>
<p>使操作生效<code>flush privileges;</code></p>
<blockquote>
<p>注意,如果启动失败,注意查看日志文件<code>/var/log/syslog</code>,这里可以找到错误原因</p>
</blockquote>
<h1 id="0x03-导入数据库"><a href="#0x03-导入数据库" class="headerlink" title="0x03 导入数据库"></a>0x03 导入数据库</h1><p>sql文件的导入</p>
<ul>
<li>进入mysql的终端:<code>mysql -u root -p</code></li>
<li>创建数据库:<code>create database databaseName;</code></li>
<li>切换数据库:<code>use databaseName;</code></li>
<li>导入文件:<code>source /root/abc.sql;</code></li>
</ul>
<h1 id="mysql连接的一个错误"><a href="#mysql连接的一个错误" class="headerlink" title="mysql连接的一个错误"></a>mysql连接的一个错误</h1><ul>
<li>错误现象:ECS中安装有mysql,也已经有mysqld服务,也开放了3306端口,但就是在本地win10用navicat连接不上(can’t connect to mysql server on ‘localhost’ (10061))</li>
<li>排查过程:检测linux上3306的监听状况。<br>使用如下命令:<code>netstat -ntpl |grep 3306</code>可以查看3306的监听状态。<br><img src="/images/mysql-basic/pic01.png" alt="pic01"></li>
<li>原因:因为3306端口的监听只与127.0.0.1绑定[1]。端口只允许本机访问,有两个地方启用,一个是防火墙启用3306,一个就是mysql配置绑定本机地址</li>
<li>修改:<br>具体参考文献[1]</li>
</ul>
<ol>
<li>编辑配置文件<code>vim /etc/mysql/mysql.conf.d/mysqld.cnf</code><br>修改一个值为:<code>bind-address = 0.0.0.0</code><br>重启服务:<code>service mysql restart</code> <br></li>
<li>另外还需要创建一个用户使外网能跟访问。<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">CREATE USER 'test'@'%' IDENTIFIED BY '1234';</span><br><span class="line">grant all privileges on mmall.* to test@'%' identified by '1234';</span><br></pre></td></tr></table></figure>
</li>
</ol>
<h1 id="附录"><a href="#附录" class="headerlink" title="附录"></a>附录</h1><p>dpkg: error processing package *** (–configure)解决办法<br><a href="https://blog.csdn.net/qq_36561697/article/details/82224279" target="_blank" rel="noopener">https://blog.csdn.net/qq_36561697/article/details/82224279</a></p>
<h1 id="参考文献"><a href="#参考文献" class="headerlink" title="参考文献"></a>参考文献</h1><p>[1] <a href="https://blog.csdn.net/qq_36820328/article/details/79654278" target="_blank" rel="noopener">https://blog.csdn.net/qq_36820328/article/details/79654278</a></p>
]]></content>
<categories>
<category>linux</category>
</categories>
<tags>
<tag>mysql</tag>
</tags>
</entry>
<entry>
<title>ngnix</title>
<url>/2020/02/13/ngnix/</url>
<content><![CDATA[<p>ngnix安装和使用<br>版本:ubuntu16.04与nginx-1.11.3</p>
<a id="more"></a>
<h1 id="0x00-简介"><a href="#0x00-简介" class="headerlink" title="0x00 简介"></a>0x00 简介</h1><ul>
<li>Ngnix是一款轻量级web服务器,也是一款反向代理服务器</li>
<li>可作为HTTP反向代理服务器,负载均衡服务器,邮件代理服务器,帮助实现前端动静分离。</li>
<li>特点:高稳定,高性能,资源占用少,功能丰富,模块化结构,支持热部署。<br><a href="http://nginx.org/" target="_blank" rel="noopener">官网</a></li>
</ul>
<h1 id="0x01-安装"><a href="#0x01-安装" class="headerlink" title="0x01 安装"></a>0x01 安装</h1><ul>
<li><p>下载软件:<br><a href="http://nginx.org/download/" target="_blank" rel="noopener">http://nginx.org/download/</a></p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">wget http://nginx.org/download/nginx-1.11.3.tar.gz</span><br></pre></td></tr></table></figure>
</li>
<li><p>安装依赖<br>centOS下的安装依赖</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">yum -y install gcc zlib zlib-devel pcre-devel openssl openssl-devel</span><br></pre></td></tr></table></figure>
</li>
</ul>
<p>ubuntu16.04 下安装依赖</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">#gcc g++的依赖库</span><br><span class="line">apt-get install build-essential</span><br><span class="line">apt-get install libtool</span><br><span class="line"># 安装pcre依赖库</span><br><span class="line">sudo apt-get update</span><br><span class="line">sudo apt-get install libpcre3 libpcre3-dev</span><br><span class="line"># 安装zlib依赖库</span><br><span class="line">apt-get install zlib1g-dev</span><br><span class="line"># 安装ssl依赖库</span><br><span class="line">apt-get install openssl</span><br></pre></td></tr></table></figure>
<ul>
<li>编译安装<br>进入解压目录<br>执行<code>./configure</code>(安装后可以通过<code>whereis ngnix</code>查询安装位置)<br>或者指定安装目录<code>./configure --prefix=/usr/local/nginx</code><br>然后执行<code>make</code>命令<br>最后执行<code>make install</code>完成安装<blockquote>
<p>通过上面可以知道ngnix安装后的位置在<code>/usr/local/nginx</code></p>
</blockquote>
</li>
</ul>
<h1 id="0x02-ngnix常用命令"><a href="#0x02-ngnix常用命令" class="headerlink" title="0x02 ngnix常用命令"></a>0x02 ngnix常用命令</h1><h2 id="测试配置文件"><a href="#测试配置文件" class="headerlink" title="测试配置文件"></a>测试配置文件</h2><p>安装路径下(eg:<code>/usr/local/nginx</code>)的<code>sbin</code>文件下的命令</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">nginx -t</span><br></pre></td></tr></table></figure>
<h2 id="启动命令"><a href="#启动命令" class="headerlink" title="启动命令"></a>启动命令</h2><p><code>sudo /usr/local/nginx/sbin/nginx</code><br>启动的时候80端口被占用的解决方案: <a href="https://jingyan.baidu.com/article/20b68a8880c84d796dec6256.html" target="_blank" rel="noopener">https://jingyan.baidu.com/article/20b68a8880c84d796dec6256.html</a><br>或者<a href="https://blog.csdn.net/qq_27252133/article/details/53646986" target="_blank" rel="noopener">98: Address already in use</a></p>
<h2 id="停止命令"><a href="#停止命令" class="headerlink" title="停止命令"></a>停止命令</h2><p><code>/usr/local/nginx/sbin/nginx -s stop</code><br>或者<br><code>/usr/local/nginx/sbin/nginx -s quit</code></p>
<h2 id="重启命令"><a href="#重启命令" class="headerlink" title="重启命令"></a>重启命令</h2><p><code>/usr/local/nginx/sbin/nginx -s reload</code></p>
<h1 id="0x03-设置虚拟域名-反向代理"><a href="#0x03-设置虚拟域名-反向代理" class="headerlink" title="0x03 设置虚拟域名(反向代理)"></a>0x03 设置虚拟域名(反向代理)</h1><ul>
<li>在ngnix的配置文件<code>./conf/nginx.conf</code>如下地方中加入如下内容<br><code>include vhost/*.conf</code><br><img src="/images/nginx/pic01.png" alt="pic"><br></li>
<li>创建vhost<br>在ngnix的conf目录下创建一个文件夹<code>vhost</code><br></li>
<li>修改host(需要访问的客户端上面的)<br>这个文件是设置域名的<br><code>vim /etc/hosts</code>,加入如下内容(win:<code>C:\Windows\System32\Drivers\etc</code>)<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">106.14.124.205 www.yijun.com</span><br><span class="line">106.14.124.205 image.yijun.com</span><br><span class="line">106.14.124.205 s.yijun.com</span><br></pre></td></tr></table></figure>
</li>
</ul>
<p>重启网络服务<code>/etc/init.d/nscd restart</code><br><br></p>
<ul>
<li>编辑节点(在目录conf/vhost下面)<br><code>cd conf/vhost</code><br>节点1: 新建<code>vim www.yijun.com.conf</code>,输入如下内容<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">server { </span><br><span class="line"> listen 80; </span><br><span class="line"> autoindex on; </span><br><span class="line"> server_name www.yijun.com; </span><br><span class="line"> access_log /usr/local/nginx/logs/access.log combined; </span><br><span class="line"> index index.html index.htm index.jsp index.php; </span><br><span class="line"> #error_page 404 /404.html; </span><br><span class="line"> if ( $query_string ~* ".*[\;'\<\>].*" ){ </span><br><span class="line"> return 404; </span><br><span class="line"> } </span><br><span class="line"> location / { </span><br><span class="line"> proxy_pass http://127.0.0.1:8080;</span><br><span class="line"> add_header Access-Control-Allow-Origin *;</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
</li>
</ul>
<p>解析:上述是把<code>www.yijun.com:80</code>的请求转发到<code>http://127.0.0.1:8080</code></p>
<blockquote>
<p>注意:<code>autoindex off</code>的时候不会暴露索引。</p>
</blockquote>
<p>重启ngnix即可<br><br>节点2:新建<code>vim image.yijun.com.conf</code>,输入如下内容</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">server { </span><br><span class="line"> listen 80; </span><br><span class="line"> autoindex off; </span><br><span class="line"> server_name image.yijun.com; </span><br><span class="line"> access_log /usr/local/nginx/logs/access.log combined; </span><br><span class="line"> index index.html index.htm index.jsp index.php; </span><br><span class="line"> #error_page 404 /404.html; </span><br><span class="line"> if ( $query_string ~* ".*[\;'\<\>].*" ){</span><br><span class="line"> return 404; </span><br><span class="line"> } </span><br><span class="line"> location ~ /(mmall_fe|mmall_admin_fe)/dist/view/* { </span><br><span class="line"> deny all;</span><br><span class="line"> } </span><br><span class="line"> location / { </span><br><span class="line"> root /myFiles;</span><br><span class="line"> add_header Access-Control-Allow-Origin *;</span><br><span class="line"> } </span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p>解析:上述是把<code>image.yijun.com:80</code>的请求转发到<code>/myFiles</code>文件夹下面。</p>
<p>重启ngnix</p>
<h1 id="参考文献"><a href="#参考文献" class="headerlink" title="参考文献"></a>参考文献</h1><p>[1] <a href="https://www.cnblogs.com/tinya/p/11849173.html" target="_blank" rel="noopener">https://www.cnblogs.com/tinya/p/11849173.html</a> ngnix安装</p>
]]></content>
<categories>
<category>linux</category>
</categories>
<tags>
<tag>ngnix</tag>
</tags>
</entry>
<entry>
<title>vsftpd</title>
<url>/2020/02/12/vsftpd/</url>
<content><![CDATA[<p>vsftpd安装和使用<br>版本:ubuntu16.04与vsftp-2.2.2</p>
<a id="more"></a>
<h1 id="0x00-介绍"><a href="#0x00-介绍" class="headerlink" title="0x00 介绍"></a>0x00 介绍</h1><p>vsftp(very secure FTP daemon),一个免费的,开源的ftp服务器软件。<br>小巧轻快,安全易用,支持虚拟用户,宽带限制。</p>
<h1 id="0x01-安装"><a href="#0x01-安装" class="headerlink" title="0x01 安装"></a>0x01 安装</h1><p><code>apt-get install vsftpd</code><br>默认的配置文件在<code>/etc/vsftpd.conf</code><br>启动服务<code>service vsftpd start</code><br>查看启动日志<code>service vsftpd status</code></p>
<h1 id="0x02-用户配置"><a href="#0x02-用户配置" class="headerlink" title="0x02 用户配置"></a>0x02 用户配置</h1><ol>
<li><p>选定一个目录作为ftp文件夹<br>如:<code>/home/uftp</code></p>
</li>
<li><p>ubuntu系统添加一个用户<br>倒数第三个是指ftp使用的文件目录</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">useradd ftpuser -d /home/ftpuser -s /bin/bash</span><br><span class="line">或者</span><br><span class="line">useradd -d /home/uftp -m uftp -s /usr/sbin/nologin</span><br></pre></td></tr></table></figure>
</li>
</ol>
<p>修改文件目录权限</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">chown -R ftpuser.ftpuser /home/ftpuser</span><br></pre></td></tr></table></figure>
<p>重设ftpuser用户的密码(123456)</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">passwd ftpuser</span><br></pre></td></tr></table></figure>
<ol start="3">
<li>配置</li>
</ol>
<ul>
<li><p>新建文件<code>vim /etc/vsftpd.user_list</code><br>用来存放允许访问ftp的用户<br>在其中加入用户名<code>ftpuser</code></p>
</li>
<li><p>配置VSFTPD文件<br><code>vim /etc/vsftpd.conf</code><br>做如下修改(后三行要放到最后)</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">write_enable=YES</span><br><span class="line">userlist_file=/etc/vsftpd.user_list</span><br><span class="line">userlist_enable=YES</span><br><span class="line">userlist_deny=NO</span><br></pre></td></tr></table></figure>
</li>
</ul>
<ol start="4">
<li><p>重启</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">service vsftpd restart</span><br><span class="line">或者</span><br><span class="line">sudo vsftpd restart</span><br></pre></td></tr></table></figure>
</li>
<li><p>验证</p>
</li>
</ol>
<p><strong>安照如上创建的用户是需要在cmd环境下进行操作</strong>,在浏览器中登陆不上。<br><code>ps aux | grep vsftpd</code>查看是否有对应进程。<br>win下的cmd中输入<code>ftp IP</code><br>下载:<code>get filename</code><br>上传:<code>put filename</code></p>
<h1 id="0x03-配置浏览器登陆"><a href="#0x03-配置浏览器登陆" class="headerlink" title="0x03 配置浏览器登陆"></a>0x03 配置浏览器登陆</h1><p>浏览器不能访问,是因为VSFTPD不支持被动模式造成的。</p>
<ol>
<li><p>编辑配置文件<code>vi /etc/vsftpd.conf</code><br>加入如下内容</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">pasv_enable=YES</span><br><span class="line">pasv_max_port=30100</span><br><span class="line">pasv_min_port=30000</span><br><span class="line"># 这儿填服务器的ip(选填)</span><br><span class="line">pasv_address=47.99.*.* </span><br><span class="line">pasv_addr_resolve=yes</span><br></pre></td></tr></table></figure>
</li>
<li><p>防火墙配置开放<br>编辑(centOS)<code>vi /etc/iptables.rules</code></p>
</li>
</ol>
<h1 id="参考文献"><a href="#参考文献" class="headerlink" title="参考文献"></a>参考文献</h1><p>[1] <a href="https://www.linuxidc.com/Linux/2017-06/144807.htm" target="_blank" rel="noopener">https://www.linuxidc.com/Linux/2017-06/144807.htm</a> Ubuntu 16.04下vsftpd 安装配置实例<br>[2] <a href="https://blog.csdn.net/sinat_41898105/article/details/90341812" target="_blank" rel="noopener">https://blog.csdn.net/sinat_41898105/article/details/90341812</a> 阿里云连接不上问题</p>
<h1 id="附录"><a href="#附录" class="headerlink" title="附录"></a>附录</h1><h2 id="centOS要用到的一个项目配置"><a href="#centOS要用到的一个项目配置" class="headerlink" title="centOS要用到的一个项目配置"></a>centOS要用到的一个项目配置</h2><figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">本项目要用到的配置项:</span><br><span class="line">#当本地用户登入时,将被更换到定义的目录下,默认值为各用户的家目录</span><br><span class="line">local_root=/ftpfile</span><br><span class="line">#使用匿名登入时,所登入的目录</span><br><span class="line">anon_root=/ftpfile</span><br><span class="line">#默认是GMT时间,改成使用本机系统时间</span><br><span class="line">use_localtime=YES</span><br><span class="line">#不允许匿名用户登录</span><br><span class="line">anonymous_enable=NO</span><br><span class="line">#允许本地用户登录</span><br><span class="line">local_enable=YES</span><br><span class="line">#本地用户可以在自己家目录中进行读写操作)</span><br><span class="line">write_enable=YES</span><br><span class="line">#本地用户新增档案时的umask值)</span><br><span class="line">local_umask=022</span><br><span class="line">#如果启动这个选项,那么使用者第一次进入一个目录时,会检查该目录下是否有.message这个档案,如果有,则会出现此档案的内容,</span><br><span class="line">#通常这个档案会放置欢迎话语,或是对该目录的说明。默认值为开启</span><br><span class="line">dirmessage_enable=YES</span><br><span class="line">#是否启用上传/下载日志记录。如果启用,则上传与下载的信息将被完整纪录在xferlog_file 所定义的档案中。预设为开启。</span><br><span class="line">xferlog_enable=YES</span><br><span class="line">#指定FTP使用20端口进行数据传输,默认值为YES</span><br><span class="line">connect_from_port_20=YES</span><br><span class="line">#如果启用,则日志文件将会写成xferlog的标准格式)</span><br><span class="line">xferlog_std_format=YES</span><br><span class="line">#这里用来定义欢迎话语的字符串)</span><br><span class="line">ftpd_banner=Welcome to mmall FTP Server</span><br><span class="line">#用于指定用户列表文件中的用户是否允许切换到上级目录)</span><br><span class="line">chroot_local_user=NO</span><br><span class="line">#设置是否启用chroot_list_file配置项指定的用户列表文件)</span><br><span class="line">chroot_list_enable=YES</span><br><span class="line">#用于指定用户列表文件)</span><br><span class="line">chroot_list_file=/etc/vsftpd/chroot_list</span><br><span class="line">#设置vsftpd服务器是否以standalone模式运行,以standalone模式运行是一种较好的方式,此时listen必须设置为YES,此为默认值。</span><br><span class="line">#建议不要更改,有很多与服务器运行相关的配置命令,需要在此模式下才有效,</span><br><span class="line">#若设置为NO,则vsftpd不是以独立的服务运行,要受到xinetd服务的管控,功能上会受到限制)</span><br><span class="line">listen=YES</span><br><span class="line">#虚拟用户使用PAM认证方式,这里是设置PAM使用的名称,默认即可,</span><br><span class="line">#与/etc/pam.d/vsftpd对应) userlist_enable=YES(是否启用vsftpd.user_list文件,黑名单,白名单都可以</span><br><span class="line">pam_service_name=vsftpd</span><br><span class="line">#被动模式使用端口范围最小值)</span><br><span class="line">pasv_min_port=61001</span><br><span class="line">#被动模式使用端口范围最大值)</span><br><span class="line">pasv_max_port=62000</span><br><span class="line">#若设置为YES,则使用PASV工作模式;若设置为NO,则使用PORT模式。默认值为YES,即使用PASV工作模式。</span><br><span class="line"># FTP协议有两种工作方式:PORT方式和PASV方式,中文意思为主动式和被动式。</span><br><span class="line"># 一、PORT#主动)方式的连接过程是:客户端向服务器的FTP端口#默认是21)发送连接请求,服务器接受连接,建立一条命令链路。</span><br><span class="line"># 当需要传送数据时,客户端在命令链路上用 PORT命令告诉服务器:“我打开了****端口,你过来连接我”。于是服务器从20端口向客户端的****端口发送连接请求,</span><br><span class="line"># 建立一条数据链路来传送数据。</span><br><span class="line"># 二、PASV#被动)方式的连接过程是:客户端向服务器的FTP端口#默认是21)发送连接请求,服务器接受连接,建立一条命令链路。</span><br><span class="line"># 当需要传送数据时,服务器在命令链路上用 PASV命令告诉客户端:“我打开了****端口,你过来连接我”。于是客户端向服务器的****端口发送连接请求,</span><br><span class="line">#建立一条数据链路来传送数据。</span><br><span class="line">#从上面可以看出,两种方式的命令链路连接方法是一样的,而数据链路的建立方法就完全不同。而FTP的复杂性就在于此。</span><br><span class="line">pasv_enable=YES(pasv_enable=YES/NO#YES)</span><br></pre></td></tr></table></figure>
<h2 id="Ununtu16-04的一个配置"><a href="#Ununtu16-04的一个配置" class="headerlink" title="Ununtu16.04的一个配置"></a>Ununtu16.04的一个配置</h2><figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">#这些设置系统默认是开启的,可以不管</span><br><span class="line">listen=NO</span><br><span class="line">listen_ipv6=YES</span><br><span class="line">dirmessage_enable=YES</span><br><span class="line">use_localtime=YES</span><br><span class="line">xferlog_enable=YES</span><br><span class="line">connect_from_port_20=YES</span><br><span class="line"></span><br><span class="line">#下面的就要自定义设置了,建议系统默认的不管,然后复制下面的</span><br><span class="line"></span><br><span class="line">#是否允许匿名访问,NO为不允许</span><br><span class="line">anonymous_enable=NO</span><br><span class="line">#是否允许本地用户访问,就是linux本机中存在的用户,YES允许</span><br><span class="line">local_enable=YES</span><br><span class="line">#是否开启写模式,YES为开启</span><br><span class="line">write_enable=YES</span><br><span class="line">#新建文件权限,一般设置为022,那么新建后的文件的权限就是777-022=755</span><br><span class="line">local_umask=022</span><br><span class="line"></span><br><span class="line">#是否启动userlist为通过模式,YES的话只有存在于userlist文件中的用户才能登录ftp(可以理解为userlist是一个白名单),NO的话,白名单失效,和下面一个参数配合使用</span><br><span class="line">userlist_enable=YES</span><br><span class="line">#是否启动userlist为禁止模式,YES表示在userlist中的用户禁止登录ftp(黑名单),NO表示黑名单失效,我们已经让userlist作为一个白名单,所以无需使用黑名单功能</span><br><span class="line">userlist_deny=NO</span><br><span class="line">#指定哪个文件作为userlist文件,我们稍后编辑这个文件</span><br><span class="line">userlist_file=/etc/vsftpd.user_list</span><br><span class="line"></span><br><span class="line">#是否限制本地所有用户切换根目录的权限,YES为开启限制,即登录后的用户不能访问ftp根目录以外的目录,当然要限制啦</span><br><span class="line">chroot_local_user=YES</span><br><span class="line">#是否启动限制用户的名单list为允许模式,上面的YES限制了所有用户,可以用这个名单作为白名单,作为例外允许访问ftp根目录以外</span><br><span class="line">chroot_list_enable=YES</span><br><span class="line">#设置哪个文件是list文件,里面的用户将不受限制的去访问ftp根目录以外的目录</span><br><span class="line">chroot_list_file=/etc/vsftpd.chroot_list</span><br><span class="line">#是否开启写模式,开启后可以进行创建文件夹等写入操作</span><br><span class="line">allow_writeable_chroot=YES</span><br><span class="line"></span><br><span class="line">#设置ftp根目录的位置,这个文件我们稍后自己创建</span><br><span class="line">local_root=/var/myftp</span><br></pre></td></tr></table></figure>
<h1 id="参考文献-1"><a href="#参考文献-1" class="headerlink" title="参考文献"></a>参考文献</h1><p>[1] <a href="https://www.mobibrw.com/2018/15389" target="_blank" rel="noopener">https://www.mobibrw.com/2018/15389</a> 错误启动解决办法</p>
]]></content>
<categories>
<category>linux</category>
</categories>
<tags>
<tag>vsftpd</tag>
</tags>
</entry>
<entry>
<title>hive01-base</title>
<url>/2020/01/14/hive01-base/</url>
<content><![CDATA[<p>hive的安装和介绍<br>版本:2.3.6<br>hadoop: 2.7.1</p>
<a id="more"></a>
<p>hive是一个基于Hadoop的数据仓库工具,用于HDFS文件中数据集的整理、查询、分析,提供一个类SQL的查询语言HiveQL(转换为MapReduce实现)。<br>以下东西来源于文献[1]<br><a href="https://hive.apache.org/" target="_blank" rel="noopener">官网</a><br><a href="https://cwiki.apache.org/confluence/display/Hive/GettingStarted" target="_blank" rel="noopener">官网手册</a></p>
<h1 id="hive安装"><a href="#hive安装" class="headerlink" title="hive安装"></a>hive安装</h1><p>安装hive,配置mysql。</p>
<h2 id="下载解压"><a href="#下载解压" class="headerlink" title="下载解压"></a>下载解压</h2><p>从官网下载安装包<code>apache-hive-2.3.6-bin.tar.gz</code><br>对文件进行解压至目录<code>/opt/hive</code><br>修改文件所属:<code>chown -R yijun:yijun hive</code></p>
<h2 id="配置环境变量"><a href="#配置环境变量" class="headerlink" title="配置环境变量"></a>配置环境变量</h2><p>这一步是可选的,可以编辑<code>/etc/profile</code>文件对所有用户都生效,也可选择<code>~/.bashrc</code>仅对当前用户生效。<br>添加如下条目:</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">export HIVE_HOME=/usr/local/hive</span><br><span class="line">export PATH=$PATH:$HIVE_HOME/bin</span><br><span class="line">export HADOOP_HOME=/usr/local/hadoop</span><br></pre></td></tr></table></figure>
<p>使用source命令使之生效</p>
<h2 id="修改配置文件"><a href="#修改配置文件" class="headerlink" title="修改配置文件"></a>修改配置文件</h2><ul>
<li><p>将<code>hive-default.xml.template</code>重命名为<code>hive-default.xml</code></p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">mv hive-default.xml.template hive-default.xml</span><br></pre></td></tr></table></figure>
</li>
<li><p>新建一个<code>hive-site.xml</code>文件<br>添加如下配置信息</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line"><?xml version="1.0" encoding="UTF-8" standalone="no"?></span><br><span class="line"><?xml-stylesheet type="text/xsl" href="configuration.xsl"?></span><br><span class="line"><configuration></span><br><span class="line"> <property></span><br><span class="line"> <name>javax.jdo.option.ConnectionURL</name></span><br><span class="line"> <value>jdbc:mysql://localhost:3306/hive?createDatabaseIfNotExist=true</value></span><br><span class="line"> <description>JDBC connect string for a JDBC metastore</description></span><br><span class="line"> </property></span><br><span class="line"> <property></span><br><span class="line"> <name>javax.jdo.option.ConnectionDriverName</name></span><br><span class="line"> <value>com.mysql.jdbc.Driver</value></span><br><span class="line"> <description>Driver class name for a JDBC metastore</description></span><br><span class="line"> </property></span><br><span class="line"> <property></span><br><span class="line"> <name>javax.jdo.option.ConnectionUserName</name></span><br><span class="line"> <value>hive</value></span><br><span class="line"> <description>username to use against metastore database</description></span><br><span class="line"> </property></span><br><span class="line"> <property></span><br><span class="line"> <name>javax.jdo.option.ConnectionPassword</name></span><br><span class="line"> <value>hive</value></span><br><span class="line"> <description>password to use against metastore database</description></span><br><span class="line"> </property></span><br><span class="line"></configuration></span><br></pre></td></tr></table></figure>
</li>
</ul>
<p>下面的内容是安装配置mysql作为元数据库</p>
<h2 id="mysql安装"><a href="#mysql安装" class="headerlink" title="mysql安装"></a>mysql安装</h2><p>安装教程见参考文献<a href="http://dblab.xmu.edu.cn/blog/install-mysql/" target="_blank" rel="noopener">2</a></p>
<p>以下是有关hive配置的步骤</p>
<ul>
<li><p>step0: 下载驱动包<br><a href="https://dev.mysql.com/downloads/connector/j/" target="_blank" rel="noopener">驱动地址</a><br>解压并拷贝<code>mysql-connector-java-5.1.40-bin.jar</code>到<code>/usr/local/hive/lib</code>目录下</p>
<br>
</li>
<li><p>step1: 新建名为hive的数据库<br>这个hive数据库与hive-site.xml中配置对应,用来保存hive元数据。</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">mysql> create database hive;</span><br><span class="line">mysql> use hive; #切换</span><br></pre></td></tr></table></figure>
</li>
<li><p>step2: 配置mysql允许hive接入<br>将所有数据库的所有表的所有权限赋给hive用户,后面的hive是配置hive-site.xml中配置的连接密码</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">mysql> grant all on *.* to hive@localhost identified by 'hive'; </span><br><span class="line">mysql> flush privileges; #刷新mysql系统权限关系表</span><br></pre></td></tr></table></figure>
</li>
</ul>
<h2 id="启动hive"><a href="#启动hive" class="headerlink" title="启动hive"></a>启动hive</h2><p>在启动之前,需要保证hadoop集群启动成功。<br><code>./bin/hive</code><br>至此,已经配置了hive,mysql作为元数据的存储库。<br>我在启动过程中的一些报错。</p>
<ul>
<li><p>如果报错信息如下,尝试启动metastor服务<code>bin/hive --servie metastore</code></p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">FAILED: SemanticException org.apache.hadoop.hive.ql.metadata.HiveException: java.lang.RuntimeException: </span><br><span class="line">Unable to instantiate org.apache.hadoop.hive.ql.metadata.SessionHiveMetaStoreClient</span><br></pre></td></tr></table></figure>
</li>
<li><p>如果报错如下:</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">Caused by: MetaException(message:Version information not found in metastore. )</span><br><span class="line"> at org.apache.hadoop.hive.metastore.RetryingHMSHandler.<init>(RetryingHMSHandler.java:83)</span><br></pre></td></tr></table></figure>
</li>
</ul>
<p>到<code>hive-site.xml</code>中加入如下条目:</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line"><property></span><br><span class="line"> <name>hive.metastore.schema.verification</name></span><br><span class="line"> <value>false</value></span><br><span class="line"></property></span><br></pre></td></tr></table></figure>
<ul>
<li>如果报错如下:<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">MetaException(message:Required table missing : "`DBS`" in Catalog "" Schema "". DataNucleus requires this table to perform its persistence operations. Either your MetaData is incorrect, or you need to enable "datanucleus.schema.autoCreateTables")</span><br><span class="line"> at org.apache.hadoop.hive.metastore.RetryingHMSHandler.<init>(RetryingHMSHandler.java:84)</span><br></pre></td></tr></table></figure>
</li>
</ul>
<p>hive元数据在远程mysql中,表明远程数据库没有相应对象。<br>解决办法如下:<code>hive-site.xml</code>中加入如下条目。</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line"><property></span><br><span class="line"> <name>datanucleus.schema.autoCreateAll</name></span><br><span class="line"> <value>true</value></span><br><span class="line"></property></span><br></pre></td></tr></table></figure>
<h1 id="hive基本操作"><a href="#hive基本操作" class="headerlink" title="hive基本操作"></a>hive基本操作</h1><p>可以查看hive支持的<a href="https://cwiki.apache.org/confluence/display/Hive/LanguageManual+Types" target="_blank" rel="noopener">数据类型</a><br>具体操作命令见文献<a href="http://dblab.xmu.edu.cn/blog/1080-2/" target="_blank" rel="noopener">1</a></p>
<h2 id="参考文献"><a href="#参考文献" class="headerlink" title="参考文献"></a>参考文献</h2><p>[1] <a href="http://dblab.xmu.edu.cn/blog/1080-2/" target="_blank" rel="noopener">http://dblab.xmu.edu.cn/blog/1080-2/</a><br>[2] <a href="http://dblab.xmu.edu.cn/blog/install-mysql/" target="_blank" rel="noopener">http://dblab.xmu.edu.cn/blog/install-mysql/</a></p>
]]></content>
<categories>
<category>bigdata</category>
</categories>
<tags>
<tag>hive</tag>
</tags>
</entry>
<entry>
<title>spark01-basic</title>
<url>/2020/01/09/spark01-basic/</url>
<content><![CDATA[<p>spark基础部分<br>安装和介绍<br>版本:spark-2.4.4-bin-hadoop2.7.tgz<br>scala 2.11.8<br>可以从清华大学镜像网站下载</p>
<a id="more"></a>
<h1 id="0x00-安装"><a href="#0x00-安装" class="headerlink" title="0x00 安装"></a>0x00 安装</h1><p><a href="http://spark.apache.org/docs/2.1.0/" target="_blank" rel="noopener">官网</a><br>部署模式有四种:</p>
<ul>
<li>Local模式(单机)</li>
<li>Standalone模式,用spark自带的简单集群管理器</li>
<li>YARN模式,使用YARN作为集群管理器</li>
<li>Mesos模式,使用Mesos作为集群管理器。</li>
</ul>
<h2 id="安装Scala环境"><a href="#安装Scala环境" class="headerlink" title="安装Scala环境"></a>安装Scala环境</h2><blockquote>
<p>Scala是一门现代的多范式编程语言,旨在以简练、优雅及类型安全的方式来表达常用编程模式,平滑地集成了面向对象和函数语言的特性,运行在JVM上,兼容java程序[1]</p>
<ul>
<li>下载Scala2.11.8和安装</li>
</ul>
</blockquote>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">wget https://downloads.lightbend.com/scala/2.11.8/scala-2.11.8.tgz</span><br><span class="line">tar -zxvf scala-2.11.8.tgz</span><br><span class="line">sudo mv scala-2.11.8 /opt/scala-2.11.8 </span><br><span class="line">sudo chown -R hadoop:hadoop /opt/scala-2.11.8</span><br></pre></td></tr></table></figure>
<ul>
<li><p>配置环境变量<br><code>vim /etc/profile</code></p>
</li>
<li><p>写入如下内容</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">export SCALA_HOME=/opt/scala-2.11.8</span><br><span class="line">export PATH=$PATH:$SCALA_HOME/bin</span><br></pre></td></tr></table></figure>
</li>
<li><p>使用source命令使之生效</p>
</li>
<li><p>验证<br><code>scala -version</code></p>
</li>
</ul>
<h2 id="安装spark"><a href="#安装spark" class="headerlink" title="安装spark"></a>安装spark</h2><ul>
<li><p>下载spark2.4.4和安装</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">wget http://mirrors.tuna.tsinghua.edu.cn/apache/spark/spark-2.4.4/spark-2.4.4-bin-hadoop2.7.tgz</span><br><span class="line">tar -zxvf spark-2.4.4-bin-hadoop2.7.tgz</span><br><span class="line">sudo mv spark-2.4.4-bin-hadoop2.7 /opt/spark-2.4.4-bin-hadoop2.7</span><br><span class="line">sudo chown -R hadoop:hadoop /opt/spark-2.4.4-bin-hadoop2.7</span><br></pre></td></tr></table></figure>
</li>
<li><p>配置日志级别<br>进入conf目录进行配置<br><code>cd /opt/spark-2.4.4-bin-hadoop2.7/conf/</code><br>使用模板创建日志配置<br><code>cp log4j.properties.template log4j.properties</code><br>修改其中的一行为如下,可以避免测试中输出太多不必要的信息<br><code>log4j.rootCategory=WARN,console</code></p>
</li>
<li><p>配置Spark环境路径<br>进入conf目录<br><code>cp ./conf/spark-env.sh.template ./conf/spark.env.sh</code><br>编辑该文件</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">export JAVA_HOME=/usr/lib/jvm/java-8-oracle</span><br><span class="line">export SPARK_HOME=/opt/spark-2.4.4-bin-hadoop2.7</span><br><span class="line">export SCALA_HOME=/opt/scala-2.11.8</span><br></pre></td></tr></table></figure>
</li>
<li><p>配置连接HDFS文件系统的信息<br>编辑<code>./conf/spark.env.sh</code>文件<br>加入如下信息,就会使用HDFS文件系统</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">export SPARK_DIST_CLASSPATH=$(/usr/local/hadoop/bin/hadoop classpath)</span><br></pre></td></tr></table></figure>
</li>
</ul>
<p>一个实例:验证配置是否成功,计算Pi的值</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">cd spark/bin</span><br><span class="line">./run-example SparkPi</span><br></pre></td></tr></table></figure>
<h1 id="0x01-Spark-shell"><a href="#0x01-Spark-shell" class="headerlink" title="0x01 Spark-shell"></a>0x01 Spark-shell</h1><h2 id="打开交互式Shell"><a href="#打开交互式Shell" class="headerlink" title="打开交互式Shell"></a>打开交互式Shell</h2><p>进入spark目录下的bin文件,可以运行一个自带的交互Shell。<br>执行命令<code>./spark-shell</code><br>退出:<code>ctrl+D</code>,或者命令<code>:quit</code><br>简单测试:<br>输入一个表达式<code>8*2+5</code>会得到一个结果<code>res0: Int=21</code></p>
<h2 id="读取linux系统本地文件"><a href="#读取linux系统本地文件" class="headerlink" title="读取linux系统本地文件"></a>读取linux系统本地文件</h2><p>可以在spark-shell窗口中读取文件,并显示第一行的内容</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">var file = sc.textFile("/etc/protocols")</span><br><span class="line">file.count()</span><br><span class="line">file.first()</span><br></pre></td></tr></table></figure>
<h2 id="读取HDFS文件"><a href="#读取HDFS文件" class="headerlink" title="读取HDFS文件"></a>读取HDFS文件</h2><p>Spark可以不用启动Hadoop就可以运行,需要使用HDFS文件系统的话就必须先启动Hadoop。</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">val textFile=sc.textFile("hdfs://localhost:9000/input/file1.txt")</span><br><span class="line">textFile.first()</span><br></pre></td></tr></table></figure>
<h1 id="0x02-Scala编写Spark应用程序"><a href="#0x02-Scala编写Spark应用程序" class="headerlink" title="0x02 Scala编写Spark应用程序"></a>0x02 Scala编写Spark应用程序</h1><p>一般都是使用IDEA进行开发,一些配置见参考文献[3],是一个词频统计程序。<br>以下介绍的手动编写配置过程,没有使用ida。<br>使用Scala语言编写的程序需要使用<strong>sbt</strong>进行编译打包</p>
<h2 id="安装sbt"><a href="#安装sbt" class="headerlink" title="安装sbt"></a>安装sbt</h2><ul>
<li><p>下载sbt-launch</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">https://repo.typesafe.com/typesafe/ivy-releases/org.scala-sbt/sbt-launch/0.13.11/sbt-launch.jar</span><br></pre></td></tr></table></figure>
</li>
<li><p>新建目录<code>/opt/sbt</code><br>改变所属组<code>chown -R yijun:yijun /opt/sbt</code><br>将下载的<code>sbt-launch.jar</code>移动到该目录下</p>
<br></li>
<li><p>在<code>/opt/sbt</code>目录下创建脚本<br><code>vim ./sbt</code><br>内容如下:</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">#!/bin/bash</span><br><span class="line">SBT_OPTS="-Xms512M -Xmx1536M -Xss1M -XX:+CMSClassUnloadingEnabled -XX:MaxPermSize=256M"</span><br><span class="line">java $SBT_OPTS -jar `dirname $0`/sbt-launch.jar "$@"</span><br></pre></td></tr></table></figure>
</li>
</ul>
<p>脚本增加可执行权限<code>chmod 755 ./sbt</code><br><br></p>
<ul>
<li>检验sbt是否可用<br><code>./sbt sbt-version</code><br>这个步骤很漫长。<br>安装成功后会显示<code>[info] 0.13.11</code>信息。</li>
</ul>
<p>之后的步骤见参考文献[1]</p>
<h2 id="编写程序"><a href="#编写程序" class="headerlink" title="编写程序"></a>编写程序</h2><ul>
<li><p>新建一个目录作为应用程序根目录,必须使用特定的文件结构(sbt要求的)</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">cd ~ </span><br><span class="line">mkdir ./sparkapp </span><br><span class="line">mkdir -p ./sparkapp/src/main/scala</span><br></pre></td></tr></table></figure>
</li>
<li><p>新建一个示例程序</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">vim ./sparkapp/src/main/scala/SimpleApp.scala</span><br></pre></td></tr></table></figure>
</li>
</ul>
<p>写入如下代码</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">/* SimpleApp.scala */</span><br><span class="line">import org.apache.spark.SparkContext</span><br><span class="line">import org.apache.spark.SparkContext._</span><br><span class="line">import org.apache.spark.SparkConf</span><br><span class="line"> </span><br><span class="line">object SimpleApp {</span><br><span class="line"> def main(args: Array[String]) {</span><br><span class="line"> #注意修改该文件的路径</span><br><span class="line"> val logFile = "file:///usr/local/spark/README.md" // Should be some file on your system</span><br><span class="line"> val conf = new SparkConf().setAppName("Simple Application")</span><br><span class="line"> val sc = new SparkContext(conf)</span><br><span class="line"> val logData = sc.textFile(logFile, 2).cache()</span><br><span class="line"> val numAs = logData.filter(line => line.contains("a")).count()</span><br><span class="line"> val numBs = logData.filter(line => line.contains("b")).count()</span><br><span class="line"> println("Lines with a: %s, Lines with b: %s".format(numAs, numBs))</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<ul>
<li>编写编译配置文件<br>在主目录下<code>./sparkapp</code>中新建文件<code>simple.sbt</code><br>添加如下内容,指定Spark和scala版本<br>其中的参数版本根据<a href="http://spark.apache.org/downloads.html" target="_blank" rel="noopener">官网设置</a><figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">name := "simple Project"</span><br><span class="line">version := "0.1"</span><br><span class="line">scalaVersion := "2.11.8"</span><br><span class="line">libraryDependencies += "org.apache.spark" %% "spark-core" % "2.4.4"</span><br></pre></td></tr></table></figure>
</li>
</ul>
<p>可以使用<code>find</code>命令查看文件结构</p>
<ul>
<li>sbt打包<br>首先一定要进入工程目录下,<code>cd ~/sparkapp</code><br>然后使用sbt命令进行打包<br>我们已经在安装sbt的步骤中写好了启动脚本<br><code>/opt/sbt/sbt package</code><br>会在<code>target</code>目录下生成jar包<br></li>
<li>运行程序<br>上一步骤生成的jar包可以通过如下命令提交到spark中去运行。<br>如果配置环境变量,使用命令(在spark的bin目录下)<code>spark-submit</code>。<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">spark-submit --class "SimpleApp" simple-project_2.10-1.0.jar</span><br></pre></td></tr></table></figure>
</li>
</ul>
<h1 id="0x03-java编写spark应用程序"><a href="#0x03-java编写spark应用程序" class="headerlink" title="0x03 java编写spark应用程序"></a>0x03 java编写spark应用程序</h1><p>来源于参考文献[4]<br>使用java语言编写sprak需使用maven工具<br><code>src/main/</code>下新建<code>SimpleApp.java</code><br>编写程序<br>pom文件中内容如下:</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line"><project></span><br><span class="line"> <groupId>edu.berkeley</groupId></span><br><span class="line"> <artifactId>simple-project</artifactId></span><br><span class="line"> <modelVersion>4.0.0</modelVersion></span><br><span class="line"> <name>Simple Project</name></span><br><span class="line"> <packaging>jar</packaging></span><br><span class="line"> <version>1.0</version></span><br><span class="line"> <repositories></span><br><span class="line"> <repository></span><br><span class="line"> <id>Akka repository</id></span><br><span class="line"> <url>http://repo.akka.io/releases</url></span><br><span class="line"> </repository></span><br><span class="line"> </repositories></span><br><span class="line"> <dependencies></span><br><span class="line"> <dependency> <!-- Spark dependency --></span><br><span class="line"> <groupId>org.apache.spark</groupId></span><br><span class="line"> <artifactId>spark-core_2.11</artifactId></span><br><span class="line"> <version>2.4.4</version></span><br><span class="line"> </dependency></span><br><span class="line"> </dependencies></span><br><span class="line"></project></span><br></pre></td></tr></table></figure>
<p>这里可以<a href="https://search.maven.org/" target="_blank" rel="noopener">查阅</a>, 搜索<code>spark-core</code><br>同样可以生成jar包,用<code>spark-submit</code>命令提交</p>
<h1 id="参考文献"><a href="#参考文献" class="headerlink" title="参考文献"></a>参考文献</h1><p>[1] <a href="http://dblab.xmu.edu.cn/blog/spark-quick-start-guide/" target="_blank" rel="noopener">http://dblab.xmu.edu.cn/blog/spark-quick-start-guide/</a><br>[2] <a href="https://www.shiyanlou.com/courses/456/learning/?id=1433" target="_blank" rel="noopener">https://www.shiyanlou.com/courses/456/learning/?id=1433</a><br>[3] <a href="http://dblab.xmu.edu.cn/blog/1492-2/" target="_blank" rel="noopener">http://dblab.xmu.edu.cn/blog/1492-2/</a><br>[4] <a href="http://dblab.xmu.edu.cn/blog/931-2/" target="_blank" rel="noopener">http://dblab.xmu.edu.cn/blog/931-2/</a></p>
]]></content>
<categories>
<category>bigdata</category>
</categories>
<tags>
<tag>spark</tag>
</tags>
</entry>
<entry>
<title>interviewMaterial</title>
<url>/2020/01/08/interviewMaterial/</url>
<content><![CDATA[<p>面试需要的知识点</p>
<h1 id="大数据"><a href="#大数据" class="headerlink" title="大数据"></a>大数据</h1><h2 id="分布式计算框架MapReduce"><a href="#分布式计算框架MapReduce" class="headerlink" title="分布式计算框架MapReduce"></a>分布式计算框架MapReduce</h2><p>一个详细的<a href="https://edu.aliyun.com/lesson_1802_15663?spm=5176.10731542.0.0.3de6244bV0ewPg#_15663" target="_blank" rel="noopener">技术参考文档</a></p>
]]></content>
<categories>
<category>interview</category>
</categories>
<tags>
<tag>interview</tag>
</tags>
</entry>
<entry>
<title>crawler</title>
<url>/2020/01/07/crawler/</url>
<content><![CDATA[<p>爬虫的一些简单实例</p>
<a id="more"></a>
<h1 id="0x00-爬取淘宝商品和价格"><a href="#0x00-爬取淘宝商品和价格" class="headerlink" title="0x00 爬取淘宝商品和价格"></a>0x00 爬取淘宝商品和价格</h1><p>使用正则和request库。<br>获取数据,对数据进行解析,然后打印输出。</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">#CrowTaobaoPrice.py</span><br><span class="line">import requests</span><br><span class="line">import re</span><br><span class="line"></span><br><span class="line">def getHTMLText(url):</span><br><span class="line"> try:</span><br><span class="line"> r = requests.get(url, timeout=30)</span><br><span class="line"> r.raise_for_status()</span><br><span class="line"> r.encoding = r.apparent_encoding</span><br><span class="line"> return r.text</span><br><span class="line"> except:</span><br><span class="line"> return ""</span><br><span class="line"> </span><br><span class="line">def parsePage(ilt, html):</span><br><span class="line"> try:</span><br><span class="line"> plt = re.findall(r'\"view_price\"\:\"[\d\.]*\"',html)</span><br><span class="line"> tlt = re.findall(r'\"raw_title\"\:\".*?\"',html)</span><br><span class="line"> for i in range(len(plt)):</span><br><span class="line"> price = eval(plt[i].split(':')[1])</span><br><span class="line"> title = eval(tlt[i].split(':')[1])</span><br><span class="line"> ilt.append([price , title])</span><br><span class="line"> except:</span><br><span class="line"> print("")</span><br><span class="line"></span><br><span class="line">def printGoodsList(ilt):</span><br><span class="line"> tplt = "{:4}\t{:8}\t{:16}"</span><br><span class="line"> print(tplt.format("序号", "价格", "商品名称"))</span><br><span class="line"> count = 0</span><br><span class="line"> for g in ilt:</span><br><span class="line"> count = count + 1</span><br><span class="line"> print(tplt.format(count, g[0], g[1]))</span><br><span class="line"> </span><br><span class="line">def main():</span><br><span class="line"> goods = '书包'</span><br><span class="line"> depth = 3</span><br><span class="line"> start_url = 'https://s.taobao.com/search?q=' + goods</span><br><span class="line"> infoList = []</span><br><span class="line"> for i in range(depth):</span><br><span class="line"> try:</span><br><span class="line"> url = start_url + '&s=' + str(44*i)</span><br><span class="line"> html = getHTMLText(url)</span><br><span class="line"> parsePage(infoList, html)</span><br><span class="line"> except:</span><br><span class="line"> continue</span><br><span class="line"> printGoodsList(infoList)</span><br><span class="line"> </span><br><span class="line">main()</span><br></pre></td></tr></table></figure>
<h1 id="0x01-静态页面的大学排名爬取"><a href="#0x01-静态页面的大学排名爬取" class="headerlink" title="0x01 静态页面的大学排名爬取"></a>0x01 静态页面的大学排名爬取</h1><p>只是用简单的正则和BeautifulSoup库<br>打印输出到屏幕</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">#CrawUnivRankingB.py</span><br><span class="line">import requests</span><br><span class="line">from bs4 import BeautifulSoup</span><br><span class="line">import bs4</span><br><span class="line"></span><br><span class="line">def getHTMLText(url):</span><br><span class="line"> try:</span><br><span class="line"> r = requests.get(url, timeout=30)</span><br><span class="line"> r.raise_for_status()</span><br><span class="line"> r.encoding = r.apparent_encoding</span><br><span class="line"> return r.text</span><br><span class="line"> except:</span><br><span class="line"> return ""</span><br><span class="line"></span><br><span class="line">def fillUnivList(ulist, html):</span><br><span class="line"> soup = BeautifulSoup(html, "html.parser")</span><br><span class="line"> for tr in soup.find('tbody').children:</span><br><span class="line"> if isinstance(tr, bs4.element.Tag):</span><br><span class="line"> tds = tr('td')</span><br><span class="line"> ulist.append([tds[0].string, tds[1].string, tds[3].string])</span><br><span class="line"></span><br><span class="line">def printUnivList(ulist, num):</span><br><span class="line"> tplt = "{0:^10}\t{1:{3}^10}\t{2:^10}"</span><br><span class="line"> print(tplt.format("排名","学校名称","总分",chr(12288)))</span><br><span class="line"> for i in range(num):</span><br><span class="line"> u=ulist[i]</span><br><span class="line"> print(tplt.format(u[0],u[1],u[2],chr(12288)))</span><br><span class="line"> </span><br><span class="line">def main():</span><br><span class="line"> uinfo = []</span><br><span class="line"> url = 'http://www.zuihaodaxue.cn/zuihaodaxuepaiming2016.html'</span><br><span class="line"> html = getHTMLText(url)</span><br><span class="line"> fillUnivList(uinfo, html)</span><br><span class="line"> printUnivList(uinfo, 20) # 20 univs</span><br><span class="line">main()</span><br></pre></td></tr></table></figure>
<h1 id="0x02-爬取股票数据"><a href="#0x02-爬取股票数据" class="headerlink" title="0x02 爬取股票数据"></a>0x02 爬取股票数据</h1><p>使用正则和BeautifulSoup库<br>结果写到文件中</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">#CrawBaiduStocksA.py</span><br><span class="line">import requests</span><br><span class="line">from bs4 import BeautifulSoup</span><br><span class="line">import traceback</span><br><span class="line">import re</span><br><span class="line"></span><br><span class="line">def getHTMLText(url):</span><br><span class="line"> try:</span><br><span class="line"> r = requests.get(url)</span><br><span class="line"> r.raise_for_status()</span><br><span class="line"> r.encoding = r.apparent_encoding</span><br><span class="line"> return r.text</span><br><span class="line"> except:</span><br><span class="line"> return ""</span><br><span class="line"></span><br><span class="line">def getStockList(lst, stockURL):</span><br><span class="line"> html = getHTMLText(stockURL)</span><br><span class="line"> soup = BeautifulSoup(html, 'html.parser') </span><br><span class="line"> a = soup.find_all('a')</span><br><span class="line"> for i in a:</span><br><span class="line"> try:</span><br><span class="line"> href = i.attrs['href']</span><br><span class="line"> lst.append(re.findall(r"[s][hz]\d{6}", href)[0])</span><br><span class="line"> except:</span><br><span class="line"> continue</span><br><span class="line"></span><br><span class="line">def getStockInfo(lst, stockURL, fpath):</span><br><span class="line"> for stock in lst:</span><br><span class="line"> url = stockURL + stock + ".html"</span><br><span class="line"> html = getHTMLText(url)</span><br><span class="line"> try:</span><br><span class="line"> if html=="":</span><br><span class="line"> continue</span><br><span class="line"> infoDict = {}</span><br><span class="line"> soup = BeautifulSoup(html, 'html.parser')</span><br><span class="line"> stockInfo = soup.find('div',attrs={'class':'stock-bets'})</span><br><span class="line"></span><br><span class="line"> name = stockInfo.find_all(attrs={'class':'bets-name'})[0]</span><br><span class="line"> infoDict.update({'股票名称': name.text.split()[0]})</span><br><span class="line"> </span><br><span class="line"> keyList = stockInfo.find_all('dt')</span><br><span class="line"> valueList = stockInfo.find_all('dd')</span><br><span class="line"> for i in range(len(keyList)):</span><br><span class="line"> key = keyList[i].text</span><br><span class="line"> val = valueList[i].text</span><br><span class="line"> infoDict[key] = val</span><br><span class="line"> </span><br><span class="line"> with open(fpath, 'a', encoding='utf-8') as f:</span><br><span class="line"> f.write( str(infoDict) + '\n' )</span><br><span class="line"> except:</span><br><span class="line"> traceback.print_exc()</span><br><span class="line"> continue</span><br><span class="line"></span><br><span class="line">def main():</span><br><span class="line"> stock_list_url = 'http://quote.eastmoney.com/stocklist.html'</span><br><span class="line"> stock_info_url = 'https://gupiao.baidu.com/stock/'</span><br><span class="line"> output_file = 'D:/BaiduStockInfo.txt'</span><br><span class="line"> slist=[]</span><br><span class="line"> getStockList(slist, stock_list_url)</span><br><span class="line"> getStockInfo(slist, stock_info_url, output_file)</span><br><span class="line"></span><br><span class="line">main()</span><br></pre></td></tr></table></figure>
<h2 id="0x03-爬取股票数据2"><a href="#0x03-爬取股票数据2" class="headerlink" title="0x03 爬取股票数据2"></a>0x03 爬取股票数据2</h2><figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">#CrawBaiduStocksB.py</span><br><span class="line">import requests</span><br><span class="line">from bs4 import BeautifulSoup</span><br><span class="line">import traceback</span><br><span class="line">import re</span><br><span class="line"></span><br><span class="line">def getHTMLText(url, code="utf-8"):</span><br><span class="line"> try:</span><br><span class="line"> r = requests.get(url)</span><br><span class="line"> r.raise_for_status()</span><br><span class="line"> r.encoding = code</span><br><span class="line"> return r.text</span><br><span class="line"> except:</span><br><span class="line"> return ""</span><br><span class="line"></span><br><span class="line">def getStockList(lst, stockURL):</span><br><span class="line"> html = getHTMLText(stockURL, "GB2312")</span><br><span class="line"> soup = BeautifulSoup(html, 'html.parser') </span><br><span class="line"> a = soup.find_all('a')</span><br><span class="line"> for i in a:</span><br><span class="line"> try:</span><br><span class="line"> href = i.attrs['href']</span><br><span class="line"> lst.append(re.findall(r"[s][hz]\d{6}", href)[0])</span><br><span class="line"> except:</span><br><span class="line"> continue</span><br><span class="line"></span><br><span class="line">def getStockInfo(lst, stockURL, fpath):</span><br><span class="line"> count = 0</span><br><span class="line"> for stock in lst:</span><br><span class="line"> url = stockURL + stock + ".html"</span><br><span class="line"> html = getHTMLText(url)</span><br><span class="line"> try:</span><br><span class="line"> if html=="":</span><br><span class="line"> continue</span><br><span class="line"> infoDict = {}</span><br><span class="line"> soup = BeautifulSoup(html, 'html.parser')</span><br><span class="line"> stockInfo = soup.find('div',attrs={'class':'stock-bets'})</span><br><span class="line"></span><br><span class="line"> name = stockInfo.find_all(attrs={'class':'bets-name'})[0]</span><br><span class="line"> infoDict.update({'股票名称': name.text.split()[0]})</span><br><span class="line"> </span><br><span class="line"> keyList = stockInfo.find_all('dt')</span><br><span class="line"> valueList = stockInfo.find_all('dd')</span><br><span class="line"> for i in range(len(keyList)):</span><br><span class="line"> key = keyList[i].text</span><br><span class="line"> val = valueList[i].text</span><br><span class="line"> infoDict[key] = val</span><br><span class="line"> </span><br><span class="line"> with open(fpath, 'a', encoding='utf-8') as f:</span><br><span class="line"> f.write( str(infoDict) + '\n' )</span><br><span class="line"> count = count + 1</span><br><span class="line"> print("\r当前进度: {:.2f}%".format(count*100/len(lst)),end="")</span><br><span class="line"> except:</span><br><span class="line"> count = count + 1</span><br><span class="line"> print("\r当前进度: {:.2f}%".format(count*100/len(lst)),end="")</span><br><span class="line"> continue</span><br><span class="line"></span><br><span class="line">def main():</span><br><span class="line"> stock_list_url = 'http://quote.eastmoney.com/stocklist.html'</span><br><span class="line"> stock_info_url = 'https://gupiao.baidu.com/stock/'</span><br><span class="line"> output_file = 'D:/BaiduStockInfo.txt'</span><br><span class="line"> slist=[]</span><br><span class="line"> getStockList(slist, stock_list_url)</span><br><span class="line"> getStockInfo(slist, stock_info_url, output_file)</span><br><span class="line"></span><br><span class="line">main()</span><br></pre></td></tr></table></figure>
]]></content>
<categories>
<category>tool</category>
</categories>
<tags>
<tag>Python</tag>
<tag>beautifulSoup</tag>
</tags>
</entry>
<entry>
<title>hadoop03-InvertIndex</title>
<url>/2020/01/07/hadoop03-InvertIndex/</url>
<content><![CDATA[<p>hadoop应用实例:倒排索引</p>
<a id="more"></a>
<h1 id="0x00问题描述"><a href="#0x00问题描述" class="headerlink" title="0x00问题描述"></a>0x00问题描述</h1><p>先看一个具体例子,我们有三个文件,如下所示。<br>file1.txt内容</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">mapreduce is simple</span><br></pre></td></tr></table></figure>
<p>file2.txt内容</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">mapreduce is powerful and simple</span><br></pre></td></tr></table></figure>
<p>file3.txt内容</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">mapreduce and mapreduce</span><br></pre></td></tr></table></figure>
<p>建立倒排索引之后应该是这样的。每一行第一个是一个单词,然后后面的字符是其出现在的文件及其出现的次数(表示权重)。</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">and file3.txt:1;file2.txt:1;</span><br><span class="line">is file2.txt:1;file1.txt:1;</span><br><span class="line">mapreduce file1.txt:1;file2.txt:1;file3.txt:2;</span><br><span class="line">powerful file2.txt:1;</span><br><span class="line">simple file2.txt:1;file1.txt:1;</span><br></pre></td></tr></table></figure>
<h1 id="0x01-mapReduce实现"><a href="#0x01-mapReduce实现" class="headerlink" title="0x01 mapReduce实现"></a>0x01 mapReduce实现</h1><p>具体需要导入的包见<code>hadoop02-wordCount</code></p>
<h2 id="map函数及其实现"><a href="#map函数及其实现" class="headerlink" title="map函数及其实现"></a>map函数及其实现</h2><figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">public static class Map extends Mapper<Object, Text, Text, Text> {</span><br><span class="line"> private Text keyInfo = new Text(); // 存储单词和URL组合</span><br><span class="line"> private Text valueInfo = new Text(); // 存储词频</span><br><span class="line"> private FileSplit split; // 存储Split对象</span><br><span class="line"> // 实现map函数</span><br><span class="line"> @Override</span><br><span class="line"> public void map(Object key, Text value, Context context) throws IOException, InterruptedException {</span><br><span class="line"> // 获得<key,value>对所属的FileSplit对象</span><br><span class="line"> split = (FileSplit) context.getInputSplit();</span><br><span class="line"> StringTokenizer itr = new StringTokenizer(value.toString());</span><br><span class="line"> while (itr.hasMoreTokens()) {</span><br><span class="line"> // key值由单词和文件名组成, value 值初始化为 1. 组成key-value对:</span><br><span class="line"> // 如: (MapReduce:file1.txt, 1)</span><br><span class="line"></span><br><span class="line"> String pathname=split.getPath().getName(); //获取目录名字</span><br><span class="line"> String thisKet = itr.nextToken() + ":"+ pathname;</span><br><span class="line"> keyInfo.set(thisKet);</span><br><span class="line"> valueInfo.set("1");</span><br><span class="line"> context.write(keyInfo, valueInfo);</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> }</span><br></pre></td></tr></table></figure>
<p>word:fileName作为key,词频作为value输出。</p>
<h2 id="combine函数及其实现"><a href="#combine函数及其实现" class="headerlink" title="combine函数及其实现"></a>combine函数及其实现</h2><figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">public static class Combine extends Reducer<Text, Text, Text, Text> {</span><br><span class="line"> private Text info = new Text();</span><br><span class="line"> // 实现reduce函数, 将相同key值的value加起来</span><br><span class="line"> // 并将(单词:文件名, value) 转换为 (单词, 文件名:value)</span><br><span class="line"> @Override</span><br><span class="line"> public void reduce(Text key, Iterable<Text> values, Context context) throws IOException, InterruptedException {</span><br><span class="line"> // 统计词频</span><br><span class="line"> int sum = 0;</span><br><span class="line"> for (Text val : values){</span><br><span class="line"> sum += Integer.parseInt(val.toString());</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> // 重新设置value值由URL和词频组成</span><br><span class="line"> String[] splitValue = key.toString().split(":");</span><br><span class="line"> String newValue = splitValue[1]+":"+ String.valueOf(sum);</span><br><span class="line"> info.set(newValue);</span><br><span class="line"> // 重新设置key值为单词</span><br><span class="line"> key.set(splitValue[0]);</span><br><span class="line"> context.write(key, info);</span><br><span class="line"> }</span><br><span class="line"> }</span><br></pre></td></tr></table></figure>
<p>统计词频,并且将(key,value)转换。</p>
<h2 id="reduce-函数及其实现"><a href="#reduce-函数及其实现" class="headerlink" title="reduce 函数及其实现"></a>reduce 函数及其实现</h2><figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">public static class Reduce extends Reducer<Text, Text, Text, Text> {</span><br><span class="line"> private Text result = new Text();</span><br><span class="line"> // 实现reduce函数, 将相同单词的value聚合成一个总的value,每个value之间用`;`隔开, 最后以`;`结尾</span><br><span class="line"> @Override</span><br><span class="line"> public void reduce(Text key, Iterable<Text> values, Context context) throws IOException, InterruptedException {</span><br><span class="line"> String item= "";</span><br><span class="line"> for(Text value : values){</span><br><span class="line"> item = item + value.toString()+ ";";</span><br><span class="line"> }</span><br><span class="line"> result.set(item.trim());</span><br><span class="line"> context.write(key, result);</span><br><span class="line"> }</span><br><span class="line"> }</span><br></pre></td></tr></table></figure>
<h2 id="main方法及其配置"><a href="#main方法及其配置" class="headerlink" title="main方法及其配置"></a>main方法及其配置</h2><figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">public static void main(String[] args) throws Exception {</span><br><span class="line"> // 第一个参数为 输入文件目录路径, 第二个参数为输出结果路径</span><br><span class="line"> Configuration conf = new Configuration();</span><br><span class="line"> conf.set("fs.defaultFS", "hdfs://localhost:9000");</span><br><span class="line"> conf.set("fs.hdfs.impl", "org.apache.hadoop.hdfs.DistributedFileSystem");</span><br><span class="line"></span><br><span class="line"> /* if (args.length != 2) {</span><br><span class="line"> System.err.println("Usage: Inverted Index <in> <out>");</span><br><span class="line"> System.exit(2);</span><br><span class="line"> }*/</span><br><span class="line"></span><br><span class="line"> Job job = new Job(conf, "Inverted Index");</span><br><span class="line"> job.setJarByClass(InvertIndex_origin.class);</span><br><span class="line"></span><br><span class="line"> // 设置Map、Combine和Reduce处理类</span><br><span class="line"> job.setMapperClass(Map.class);</span><br><span class="line"> job.setCombinerClass(Combine.class);</span><br><span class="line"> job.setReducerClass(Reduce.class);</span><br><span class="line"></span><br><span class="line"> // 设置Map输出类型</span><br><span class="line"> job.setMapOutputKeyClass(Text.class);</span><br><span class="line"> job.setMapOutputValueClass(Text.class);</span><br><span class="line"></span><br><span class="line"> // 设置Reduce输出类型</span><br><span class="line"> job.setOutputKeyClass(Text.class);</span><br><span class="line"> job.setOutputValueClass(Text.class);</span><br><span class="line"></span><br><span class="line"> // 设置输入和输出目录</span><br><span class="line"> String input_path = "/input";</span><br><span class="line"> String out_path = "/output";</span><br><span class="line"> FileInputFormat.addInputPath(job, new Path(input_path));</span><br><span class="line"> FileOutputFormat.setOutputPath(job, new Path(out_path));</span><br><span class="line"> System.exit(job.waitForCompletion(true) ? 0 : 1);</span><br><span class="line"> }</span><br></pre></td></tr></table></figure>
]]></content>
<categories>
<category>bigdata</category>
</categories>
<tags>
<tag>hadoop</tag>
</tags>
</entry>
<entry>
<title>hadoop02-wordCount</title>
<url>/2020/01/07/hadoop02-wordCount/</url>
<content><![CDATA[<p>hadoop的一个应用实例:词频统计及其理论介绍</p>
<a id="more"></a>
<h1 id="0x00-实例代码"><a href="#0x00-实例代码" class="headerlink" title="0x00 实例代码"></a>0x00 实例代码</h1><p>一个简单介绍MapReduce技术的<a href="https://edu.aliyun.com/lesson_1802_15663?spm=5176.10731542.0.0.824e244b8wdsOb#_15663" target="_blank" rel="noopener">文档</a><br>见官网提供的词频统计示例:<a href="https://hadoop.apache.org/docs/r2.7.2/hadoop-mapreduce-client/hadoop-mapreduce-client-core/MapReduceTutorial.html" target="_blank" rel="noopener">官网词频统计</a></p>
<h2 id="一个测试用例"><a href="#一个测试用例" class="headerlink" title="一个测试用例"></a>一个测试用例</h2><p>test.txt</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">Bye GoogBye Hadoop Hello Word Hadoop Word</span><br></pre></td></tr></table></figure>
<h2 id="首先实现一个Mapper类"><a href="#首先实现一个Mapper类" class="headerlink" title="首先实现一个Mapper类"></a>首先实现一个Mapper类</h2><p>具体需要导入的包见官方示例。这里用到的都是hadoop中重新定义的类型,保证能序列化和反序列化。<br>对应如下:</p>
<blockquote>
<p>Long === LongWritable<br>String === Text<br>Integer === IntWritable</p>
</blockquote>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">public static class TokenizerMapper</span><br><span class="line"> extends Mapper<Object, Text, Text, IntWritable>{</span><br><span class="line"></span><br><span class="line"> private final static IntWritable one = new IntWritable(1);</span><br><span class="line"> private Text word = new Text();</span><br><span class="line"></span><br><span class="line"> public void map(Object key, Text value, Context context</span><br><span class="line"> ) throws IOException, InterruptedException {</span><br><span class="line"> StringTokenizer itr = new StringTokenizer(value.toString());</span><br><span class="line"> while (itr.hasMoreTokens()) {</span><br><span class="line"> word.set(itr.nextToken());</span><br><span class="line"> context.write(word, one);</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> }</span><br></pre></td></tr></table></figure>
<p>该方法定义的输入是<code><Object, Text></code>,输出是<code><Text, IntWritable></code>。StringTokenizer是<code>java.util</code>包下分割字符串工具。通过write方法将结果输出到文件中去。<br>该map输出结果如下:</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">< Bye, 1></span><br><span class="line">< GoodBye, 1></span><br><span class="line"><Hadoop, (1,1)></span><br><span class="line">< Hello, 1></span><br><span class="line">< World, (1,1)></span><br></pre></td></tr></table></figure>
<p>如果设置了combiner操作<code>job.setCombinerClass(IntSumReducer.class)</code>,则会进行合并操作。<strong>每次运行完map,会对输出按照key进行排序,把输出传递给本地combiner,进行本地聚合。</strong><br>可以见到,词频统计的combiner和reduce操作是一样的流程。combiner(按照配置可以知道和reduce一样),<br>经过combiner后,map输出如下:</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">< Bye, 1></span><br><span class="line">< GoodBye, 1></span><br><span class="line"><Hadoop, 2></span><br><span class="line">< Hello, 1></span><br><span class="line">< World, 2></span><br></pre></td></tr></table></figure>
<h2 id="实现一个Reduce类"><a href="#实现一个Reduce类" class="headerlink" title="实现一个Reduce类"></a>实现一个Reduce类</h2><p>经过map和combiner后,reduce收到的数据是这样的</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line"><Bye, [1]></span><br><span class="line"><GoodBye, [1]></span><br><span class="line"><Hadoop, [1,1]></span><br><span class="line"><hello, [1]></span><br><span class="line"><World, [1]></span><br></pre></td></tr></table></figure>
<p>之后进行reduce操作。</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">public static class IntSumReducer</span><br><span class="line"> extends Reducer<Text,IntWritable,Text,IntWritable> {</span><br><span class="line"> private IntWritable result = new IntWritable();</span><br><span class="line"></span><br><span class="line"> public void reduce(Text key, Iterable<IntWritable> values,</span><br><span class="line"> Context context</span><br><span class="line"> ) throws IOException, InterruptedException {</span><br><span class="line"> int sum = 0;</span><br><span class="line"> for (IntWritable val : values) {</span><br><span class="line"> sum += val.get();</span><br><span class="line"> }</span><br><span class="line"> result.set(sum);</span><br><span class="line"> context.write(key, result);</span><br><span class="line"> }</span><br><span class="line"> }</span><br></pre></td></tr></table></figure>
<p>将相同key的值进行操作,对不同map的输出进行汇总。</p>
<h2 id="编写main方法"><a href="#编写main方法" class="headerlink" title="编写main方法"></a>编写main方法</h2><figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">public static void main(String[] args) throws Exception {</span><br><span class="line"> Configuration conf = new Configuration();</span><br><span class="line"> Job job = Job.getInstance(conf, "word count");</span><br><span class="line"> job.setJarByClass(WordCount.class);</span><br><span class="line"> job.setMapperClass(TokenizerMapper.class);</span><br><span class="line"> job.setCombinerClass(IntSumReducer.class);</span><br><span class="line"> job.setReducerClass(IntSumReducer.class);</span><br><span class="line"> job.setOutputKeyClass(Text.class);</span><br><span class="line"> job.setOutputValueClass(IntWritable.class);</span><br><span class="line"> FileInputFormat.addInputPath(job, new Path(args[0]));</span><br><span class="line"> FileOutputFormat.setOutputPath(job, new Path(args[1]));</span><br><span class="line"> System.exit(job.waitForCompletion(true) ? 0 : 1);</span><br><span class="line"> }</span><br></pre></td></tr></table></figure>
<p>这个方法使设置job的一些配置,主要涉及map类,reduce类。输出的key, value类型。设置作业的输入,输出路径。<br>要想程序能跟运行,还需要连接hdfs系统。有两种方法,把core.xml放到资源文件下,或加入如下的代码:</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">conf.set("fs.defaultFS", "hdfs://localhost:9000");</span><br><span class="line">conf.set("fs.hdfs.impl", "org.apache.hadoop.hdfs.DistributedFileSystem");</span><br></pre></td></tr></table></figure>
<h1 id="0x01-一些问题"><a href="#0x01-一些问题" class="headerlink" title="0x01 一些问题"></a>0x01 一些问题</h1><p>Q1:为什么不用JAVA的序列化?<br>A1:java序列化是一个重量级框架(Serializable),一个对象序列化后有许多额外的信息如校验信息,Header,继承体系)。不便在网络中高效传输,所以Hadoop开发了自己的序列化机制(Writable)。</p>
<p>Q2: mapreduce有哪些进程<br>A2: 有三类实例进程:</p>
<blockquote>
<ul>
<li>MrAppMaster: 负责过程调度及状态协调</li>
<li>MapTask: 负责Map阶段的数据处理流程</li>
<li>ReduceTask: 负责Reduce阶段的整个数据处理流程,对每一组相同的<k,v>调用一次reduce方法。</li>
</ul>
</blockquote>
<h1 id="0x02-mapReduce框架原理"><a href="#0x02-mapReduce框架原理" class="headerlink" title="0x02 mapReduce框架原理"></a>0x02 mapReduce框架原理</h1><h2 id="InputFormat数据输入"><a href="#InputFormat数据输入" class="headerlink" title="InputFormat数据输入"></a>InputFormat数据输入</h2><p>数据块:Block是HDFS在物理上把数据分成一块一块。<br>数据切片:在逻辑上对输入进行分片。<br>一个Job的map阶段并行度由客户端在提交Job时的切片数决定,每一个Split切片分配一个MapTask实例。切片是针对每一个文件单独切片。</p>
<h1 id="0x03-mapReduce开发过程"><a href="#0x03-mapReduce开发过程" class="headerlink" title="0x03 mapReduce开发过程"></a>0x03 mapReduce开发过程</h1><h2 id="1-输入数据接口:InputFormat"><a href="#1-输入数据接口:InputFormat" class="headerlink" title="1. 输入数据接口:InputFormat"></a>1. 输入数据接口:InputFormat</h2><ul>
<li>默认使用实现类是<code>TextInputFormat</code>:一次读一行文本,然后将该行的起始字节偏移量作为key,行内容(不包括换行和回车)作为value值返回。</li>
<li><code>KeyValueTextInputFormat</code>每一行均为一条记录,被分割符分割为key,value。默认分隔符是tab(‘\t’)。</li>
<li><code>NlineInputFormat</code>按照指定的行数N来划分切片,每一个切片对应一个MapTask。</li>
<li><code>CombineTextInputFormat</code>把多个小文件合并成一个切片处理,提高处理效率。</li>
<li>用户可以自定义<code>InputFormat</code>。</li>
</ul>
<h2 id="2-逻辑处理接口-Mapper"><a href="#2-逻辑处理接口-Mapper" class="headerlink" title="2. 逻辑处理接口:Mapper"></a>2. 逻辑处理接口:Mapper</h2><p>用户根据业务需求有选择的实现三个方法:<code>map()</code>,<code>setup()</code>,<code>cleanup()</code></p>
<h2 id="3-Partitioner分区"><a href="#3-Partitioner分区" class="headerlink" title="3. Partitioner分区"></a>3. Partitioner分区</h2><ul>
<li>有默认实现<code>HashPartitioner</code>,根据key的哈希值和numReduces返回一个分区号。用户无法控制哪个key存储到那个分区。</li>
<li>也可以自定义分区。</li>
</ul>
<h2 id="4-Comparable排序"><a href="#4-Comparable排序" class="headerlink" title="4. Comparable排序"></a>4. Comparable排序</h2><p>用自定义对象作为key来输出是,就必须实现WritableComparable接口,重写其中的compareTo()方法。<br>部分排序:对最终输出的每一个文件进行内部排序。<br>全排序:对所有数据进行排序,通常只有一个Reduce。<br>二次排序:排序条件有两个。</p>
<h2 id="5-Combiner合并"><a href="#5-Combiner合并" class="headerlink" title="5. Combiner合并"></a>5. Combiner合并</h2><p>提高执行效率,减少IO开销</p>
<h2 id="6-Reduce端分组:GroupingComparator"><a href="#6-Reduce端分组:GroupingComparator" class="headerlink" title="6.Reduce端分组:GroupingComparator"></a>6.Reduce端分组:GroupingComparator</h2><p>在Reduce端进行key分组。应用于接受key为对象时,想让一个或几个字段相同的key进入同一个reduce方法。</p>
<h2 id="7-逻辑处理接口"><a href="#7-逻辑处理接口" class="headerlink" title="7.逻辑处理接口"></a>7.逻辑处理接口</h2><p>根据业务需求实现三个方法:<code>reduce()</code>, <code>setup()</code>, <code>cleanup()</code>。</p>
<h2 id="8-数据输出接口"><a href="#8-数据输出接口" class="headerlink" title="8.数据输出接口"></a>8.数据输出接口</h2><ul>
<li>默认实现是<code>TextOutputFormat</code>,将每一个kv对,向目标文件中输出一行。</li>
<li><code>SequenceFileOutputFormat</code>输出作为后续MapReduce任务的输入。</li>
<li>可以自定义<code>OutputFormat</code></li>
</ul>
<h1 id="参考文献"><a href="#参考文献" class="headerlink" title="参考文献"></a>参考文献</h1><p>[1] <a href="https://edu.aliyun.com/lesson_1802_15663?spm=5176.10731542.0.0.824e244b8wdsOb#_15663" target="_blank" rel="noopener">https://edu.aliyun.com/lesson_1802_15663?spm=5176.10731542.0.0.824e244b8wdsOb#_15663</a></p>
]]></content>
<categories>
<category>bigdata</category>
</categories>
<tags>
<tag>hadoop</tag>
</tags>
</entry>
<entry>
<title>linux-basic</title>
<url>/2019/12/07/linux-basic/</url>
<content><![CDATA[<p>Linux入门<br>学习linux的一些基本操作</p>
<a id="more"></a>
<p>更改主机名<br><code>hostname</code>查看主机名<br><code>hostname Name</code>临时更改<br><code>vim /etc/hostname</code>永久修改<br>查看系统版本<code>cat /etc/issue</code></p>
<h1 id="0x00-文件操作"><a href="#0x00-文件操作" class="headerlink" title="0x00 文件操作"></a>0x00 文件操作</h1><h2 id="cp命令"><a href="#cp命令" class="headerlink" title="cp命令"></a>cp命令</h2><p>功能:用于目录或者文件的复制<br>格式:<code>cp [options] file destination</code><br>举例:</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">cp a.txt b.txt 重新创建新的时间戳</span><br><span class="line">cp -p a.txt b.txt 不改变时间戳,所属用户</span><br><span class="line">cp -r a b 递归复制,用于文件夹</span><br></pre></td></tr></table></figure>
<h2 id="mv命令"><a href="#mv命令" class="headerlink" title="mv命令"></a>mv命令</h2><p>功能:移动和重命名文件或者目录<br>格式:<code>mv [option] src des</code><br>举例:</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">mv a ab 重命名</span><br><span class="line">mv a ../ 移动a到上层目录</span><br></pre></td></tr></table></figure>
<h2 id="rm命令"><a href="#rm命令" class="headerlink" title="rm命令"></a>rm命令</h2><p><code>rm -rf filename</code></p>
<h1 id="0x01系统管理"><a href="#0x01系统管理" class="headerlink" title="0x01系统管理"></a>0x01系统管理</h1><h2 id="监控系统状态"><a href="#监控系统状态" class="headerlink" title="监控系统状态"></a>监控系统状态</h2><h3 id="w命令"><a href="#w命令" class="headerlink" title="w命令"></a>w命令</h3><p>功能:查看系统当前负载<br>时间,系统运行时间,登陆用户数,平均负载。<br>这里特别要注意评价负载中的第一个值:表示1分钟内的系统评价负载(单位时间内使用CPU的活动进程数)。如果小于CPU的数量就OK,否则系统有压力。</p>
<blockquote>
<p>查看CPU的个数/核: <code>cat /proc/cpuinfo</code></p>
</blockquote>
<h3 id="vmstat"><a href="#vmstat" class="headerlink" title="vmstat"></a>vmstat</h3><p>功能:监控系统状态<br>用法:不加参数不会刷新,加参数会刷新<code>vmstat 1</code>(1秒刷新一次),或者<code>vmstat 1 5</code>刷新五次<br>解释:</p>
<ul>
<li>r:运行或者等待CPU时间片的进程数,等待非CPU资源的进程数。</li>
<li>swpd:切换到变换分区的内存数量(KB),free:空闲内存数(KB),buff:将写入磁盘缓冲大小的数(KB),cache:磁盘读取的缓冲大小(KB)</li>
<li>si:变换区写入内存的大小(KB,),so:内存写入变换区的数量,<strong>值大说明内存不够</strong></li>
<li>bi:从块设备中读取的数据量KB,bo:写入块设备的数据量。</li>
<li>in:某一个时间间隔观测到的每秒设备中断次数,cs:每秒产生上下文切换次数</li>
<li>us:用户所花费CPU时间百分比,sy:系统花费CPU时间百分比,id:cpu处于空闲时间段的百分比,wa:IO等待所占用CPU百分比,st:被偷走的CPU所占百分比。</li>
</ul>
<h3 id="top"><a href="#top" class="headerlink" title="top"></a>top</h3><p>功能:显示进程所占系统资源,3s变换一次<br>占用系统资源(CPU,内存,磁盘)最高进程放前面<br><code>top -bn1</code>非动态打印使用情况。</p>
<h3 id="free"><a href="#free" class="headerlink" title="free"></a>free</h3><p>功能:查看内存使用情况<br><code>free -h</code></p>
<h3 id="ps"><a href="#ps" class="headerlink" title="ps"></a>ps</h3><p>查看系统所有进程<br><code>ps aux</code>和<code>ps au</code><br>暴力删掉进程:<code>kill -9 PID</code><br>进程状态:D:不能中断的进程,R:正在运行的进程,S:已经中断的进程,s:主进程,T:已经停止暂停的进程,z:僵尸进程,<:高优先级进程,l:多线程进程,+:前台运行的进程</p>
<h3 id="netstat"><a href="#netstat" class="headerlink" title="netstat"></a>netstat</h3><p>功能:查看网络连接状况,系统开发端口,路由表等信息</p>
<blockquote>
<p><code>-r</code>查看路由表(netstat -r)</p>
</blockquote>
<p><code>netstat -lnp</code>该命令表示系统启用的端口<br><code>netstat -lnp | head -n30</code><br>上面一部分监听TCP/IP,下面监听Socket(unix开头)<br><code>netstat -an</code> 查看网络连接状况<br>如<code>netstat -an | grep 80</code>可以查看web服务器连接的IP</p>
<h2 id="磁盘管理"><a href="#磁盘管理" class="headerlink" title="磁盘管理"></a>磁盘管理</h2><h3 id="查看磁盘"><a href="#查看磁盘" class="headerlink" title="查看磁盘"></a>查看磁盘</h3><p><code>df -h</code>或者<code>df -h | grep -v tmpfs</code></p>
<h3 id="查看文件或者目录"><a href="#查看文件或者目录" class="headerlink" title="查看文件或者目录"></a>查看文件或者目录</h3><p><code>du -sh filename</code></p>
<h1 id="0x02文本编辑"><a href="#0x02文本编辑" class="headerlink" title="0x02文本编辑"></a>0x02文本编辑</h1><p>这里介绍的是vi或则vim编辑器,涉及到命令模式,编辑模式</p>
<h2 id="打开文件"><a href="#打开文件" class="headerlink" title="打开文件"></a>打开文件</h2><p><code>vim test.txt</code> 打开文件定位到第一行行首<br><code>vim test.txt +6</code>打开文件并且定位于第6行<br><code>vim test.txt +</code> 打开文件并且定位于最后一行<br><code>vim test.txt +/pattern</code> 打开文件并且定位到第一次匹配到pattern的行首</p>
<h2 id="移动光标"><a href="#移动光标" class="headerlink" title="移动光标"></a>移动光标</h2><p><code>h</code>左,<code>l</code>右,<code>k</code>上,<code>j</code>下<br><code>ctrl+B</code>向前翻一页,<code>ctrl+F</code>向后翻一页,<code>gg</code>首行,<code>G</code>行尾,<code>nG</code>任意行(n为数字)<br><code>shift+6</code>本行行首,<code>shift+4</code>本行行尾</p>
<h2 id="进入编辑模式"><a href="#进入编辑模式" class="headerlink" title="进入编辑模式"></a>进入编辑模式</h2><p><code>i</code>向前插入,<code>a</code>向后插入,<code>I</code>行首插入,<code>A</code>行尾插入,<code>o</code>下一行插入,<code>O</code>上一行插入</p>
<h2 id="文本操作"><a href="#文本操作" class="headerlink" title="文本操作"></a>文本操作</h2><p><code>x</code>向后删除一个字符,<code>X</code>向前删除一个字符,<code>nx</code>向后删除n个字符<br><code>dd</code>剪切光标所在行,<code>ndd</code>向后剪切n行<br><code>yy</code>复制光标所在行,<code>nyy</code>向后复制n行<br><code>p</code>向光标所在行下复制,<code>P</code>向上复制<br><code>u</code>还原上一步操作,<code>v</code>选定字符</p>
<h2 id="命令模式"><a href="#命令模式" class="headerlink" title="命令模式"></a>命令模式</h2><p><code>:set nu</code>显示行号,<code>:w</code>保存,<code>:w!</code>强制保存,<code>:wq</code>保存并推出,<code>:q!</code>强退,改动不生效,<code>:set nonu</code>不显示行号,<code>:!cmd</code>执行shell命令<br><code>:set paste</code>粘贴<br><code>/word</code>向光标后查询word,n向后搜索<br><code>?word</code>向光标前查询word,n向前搜索<br><code>:n1,n2s/word1/word2/g</code>n1和n2行之间查询word1并替换为word2,不加g只替换每行第一个<br><code>:1,$s/word1/word2/g</code>全文查询word1并替换为word2,不加g只替换每行第一个</p>
<h1 id="0x03压缩与打包"><a href="#0x03压缩与打包" class="headerlink" title="0x03压缩与打包"></a>0x03压缩与打包</h1><p>一些格式:<br><code>.gz</code>使用gzip压缩的文件,<code>.bz2</code>使用bizp2压缩的文件,<code>.tar</code>使用tar打包的文件或者目录,无压缩功能<br><code>.tar.gz</code>先tar打包,再gzip压缩,<code>.tar.bz2</code>先tar打包,再bzip2压缩,<code>.tar.xz</code>先tar打包,再xz压缩</p>
<h2 id="tar"><a href="#tar" class="headerlink" title="tar"></a>tar</h2><p>格式: <code>tar [-zjxcvfpP] filename</code><br>参数说明:<br><code>-z</code>:打包同时使用gzip压缩,<code>-j</code>:同时使用bzip2压缩,<code>-J</code>:同时使用xz压缩<br><code>-x</code>:解包或者解压,<code>-c</code>建立一个tar包或者压缩包<br><code>-v</code>可视化,,<code>-t</code>查看文件,<code>-f</code>操作的文件<br>举例:</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">tar -cvf a.tar a 将文件或目录a打包成a.tar</span><br><span class="line">tar -czvf a.tar.gz a 将文件或者目录打包并使用gzip压缩</span><br><span class="line">tar -tf a.tar.gz 查看文件列表</span><br><span class="line">tar -zxvf a.tar.gz 解压</span><br></pre></td></tr></table></figure>
<h2 id="zip"><a href="#zip" class="headerlink" title="zip"></a>zip</h2><p>上面列举的三个都不支持压缩目录,该工具支持压缩目录,但是要压缩需要指定目录下的文件<br>压缩:<code>zip test.zip test/*</code><br><code>zip -r test.zip test/</code> 一并压缩二级目录,不需要星号了<br>解压:<code>unzip test.zip</code></p>
<h1 id="0x04软件安装"><a href="#0x04软件安装" class="headerlink" title="0x04软件安装"></a>0x04软件安装</h1><h2 id="ubuntu系统下"><a href="#ubuntu系统下" class="headerlink" title="ubuntu系统下"></a>ubuntu系统下</h2><p>一般使用<code>apt-get</code>。apt-get命令适用于deb包管理式的Linux操作系统(Debian、Ubuntu等),主要用于自动从互联网软件仓库中搜索、下载、安装、升级、卸载软件或操作系统[2]。<br>普通安装<code>apt-get install PackageName</code><br>重新安装<code>apt-get --reinstall install PackageName</code><br>修复依赖关系<code>apt-get -f install</code><br>下载源码<code>apt-get source PackageName</code><br>删除软件包,保留配置文件<code>apt-get remove PackageName</code><br>删除软件包,同时删除配置文件<code>apt-get purge PackageName</code><br>清楚已经下载的软件包和旧安装包<code>apt-get clean && apt-get autoclean</code><br>更新安装源<code>apt-get update</code><br>列出已经安装的所有软件包<code>dpkg -l</code></p>
<p>安装.deb格式的软件安装包<code>dpkg -i xxxx.deb</code></p>
<h1 id="0x05正则表达式与流式编辑工具"><a href="#0x05正则表达式与流式编辑工具" class="headerlink" title="0x05正则表达式与流式编辑工具"></a>0x05正则表达式与流式编辑工具</h1><h2 id="正则基础"><a href="#正则基础" class="headerlink" title="正则基础"></a>正则基础</h2><p><code>.</code> 匹配任意单个字符<br><code>?</code> 匹配0到1次<br><code>*</code> 匹配0到多次<br><code>+</code> 匹配1到多次<br><code>{n}</code> 匹配n次<br><code>{n,}</code>匹配n到多次;<code>{n,m}</code>匹配n到m次<br><code>.*</code>匹配任意字符<br><code>^</code>行首,<code>$</code>行尾 <code>\<</code>,<code>\></code>单词首尾边界<br><code>|</code> 连接操作符<br><code>[]</code>字符序列单字符占位</p>
<h2 id="grep-egrep"><a href="#grep-egrep" class="headerlink" title="grep/egrep"></a>grep/egrep</h2><p>功能:流式文本工具,面向行编辑<br>命令格式:<code>grep [-cinvABC] pattern fileName</code><br>说明:<code>-c</code>打印符合要求的行数,<code>-i</code>忽略大小写,<code>-n</code>输出符号要求的行和行号,<code>-v</code>输出不符合要求的行,<code>-A number</code>输出符合要求的行及下两行,<code>-B number</code> 行及上两行,<code>-c number</code>行及上下各两行,<code>-e</code>使用扩展的正则表达式。<br>正则式+是不能再grep中使用的<br>举例:</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">grep -B 2 'df' test.txt 打印出test.txt中字符串df的行及上两行,也可写成-B2</span><br><span class="line">grep -n 'df' test.txt 打印出df所在行及行号</span><br><span class="line">grep -nv 'df' test.txt 打印没有df的行及行号</span><br><span class="line">grep '[0-9]' test.txt 过滤出数字行</span><br><span class="line">grep -v '^#' test.txt 过滤掉所有#开头的行</span><br><span class="line">grep -e '[0-9]{4} test.txt 不加-e的话就需要这样写 grep "[0-9]\{4\}" test.txt</span><br><span class="line">grep "<ooxx>" test.txt 选出包含单词ooxx的行</span><br></pre></td></tr></table></figure>
<h1 id="0x06-一些实用技巧"><a href="#0x06-一些实用技巧" class="headerlink" title="0x06 一些实用技巧"></a>0x06 一些实用技巧</h1><h2 id="免密登陆设置"><a href="#免密登陆设置" class="headerlink" title="免密登陆设置"></a>免密登陆设置</h2><figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">cd ~</span><br><span class="line">ssh-keygen -t rsa</span><br><span class="line">touch authorized_keys</span><br><span class="line">cat id_rsa.pub >> authorized_keys</span><br><span class="line">chmod 600 authorized_keys</span><br></pre></td></tr></table></figure>
<h2 id="终端root命令颜色配置"><a href="#终端root命令颜色配置" class="headerlink" title="终端root命令颜色配置"></a>终端root命令颜色配置</h2><p>具体见参考文献[3]<br>颜色的设置公式<br><code>颜色=\033[代码;前景;背景m</code><br>不加任何颜色:<br><code>PS1='\u@\h:\w\$'</code><br><br><br>用户名以红色显示的命令应该是:<br><code>PS1='\[\033[1;31;40m\]\u@\h:\w\$'</code></p>
<blockquote>
<p>全部非打印字符用专用的 bash 转义序列 <code>\[</code>和 <code>\]</code>括起来<br><br></p>
</blockquote>
<p>以防止整个信息项以红色显示,修改后的PS1变量为:<br><code>PS1='\[\033[1;31;40m\]\u\[\033[00m\]@\h:\w\$ '</code><br><br><br>加一个命令行绿色的(<strong>推荐这个</strong>)</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">PS1='\[\033[1;31;40m\]\u\[\033[00m\]@\h:\[\033[37;40m\]\w\[\033[32;40m\]\$ \[\033[32;40m\]'</span><br></pre></td></tr></table></figure>
<p>设置示例:<br>打开<code>~/.bashrc</code>,在最后一行加入</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">PS1='${debian_chroot:+($debian_chroot)}\[\033[01;35;40m\]\u\[\033[00;00;40m\]@\[\033[01;35;40m\]\h\[\033[00;31;40m\]:\[\033[00;00;40m\]\w \[\033[01;32;40m\]\$ \[\033[01;36;40m\]'</span><br></pre></td></tr></table></figure>
<p>保存退出,source使之生效<br>这个颜色</p>
<h1 id="参考文献"><a href="#参考文献" class="headerlink" title="参考文献"></a>参考文献</h1><p>[1] <a href="http://www.apelearn.com/study_v2/" target="_blank" rel="noopener">http://www.apelearn.com/study_v2/</a><br>[2] <a href="https://blog.csdn.net/xietansheng/article/details/80044644" target="_blank" rel="noopener">https://blog.csdn.net/xietansheng/article/details/80044644</a><br>[3] <a href="http://blog.chinaunix.net/uid-26021340-id-3481924.html" target="_blank" rel="noopener">http://blog.chinaunix.net/uid-26021340-id-3481924.html</a></p>
]]></content>
<categories>
<category>linux</category>
</categories>
<tags>
<tag>linux</tag>
</tags>
</entry>
<entry>
<title>software-intro</title>
<url>/2019/12/04/software-intro/</url>
<content><![CDATA[<p>software library</p>
<a id="more"></a>
<h1 id="代码阅读"><a href="#代码阅读" class="headerlink" title="代码阅读"></a>代码阅读</h1><h2 id="Understand"><a href="#Understand" class="headerlink" title="Understand"></a>Understand</h2><p>以直观地看到项目结构和规模,灰框代表一个文件夹,蓝色方块代表了一个文件,其大小和颜色分别反映了行数和文件复杂度。</p>
<h1 id="终端神器"><a href="#终端神器" class="headerlink" title="终端神器"></a>终端神器</h1><h2 id="MobaXterm"><a href="#MobaXterm" class="headerlink" title="MobaXterm"></a>MobaXterm</h2><p>一个全能的终端神器,shell, vnc, sftp等功能。</p>
<h1 id="压缩软件"><a href="#压缩软件" class="headerlink" title="压缩软件"></a>压缩软件</h1><h2 id="7zG"><a href="#7zG" class="headerlink" title="7zG"></a>7zG</h2><p>7-zip 轻量级,支持zip,rar,7z,tar.gz等格式</p>
<h1 id="垃圾清理软件"><a href="#垃圾清理软件" class="headerlink" title="垃圾清理软件"></a>垃圾清理软件</h1><p>CCleaner</p>
<h1 id="文献管理"><a href="#文献管理" class="headerlink" title="文献管理"></a>文献管理</h1><p>EndNote</p>
<h1 id="笔记"><a href="#笔记" class="headerlink" title="笔记"></a>笔记</h1><p>印象笔记,WizNote, Notepad++,vscode</p>
<h1 id="文档搜索"><a href="#文档搜索" class="headerlink" title="文档搜索"></a>文档搜索</h1><p>everything</p>
<h1 id="数据库管理"><a href="#数据库管理" class="headerlink" title="数据库管理"></a>数据库管理</h1><p>navicat</p>
<h1 id="http请求"><a href="#http请求" class="headerlink" title="http请求"></a>http请求</h1><p>postman</p>
<h1 id="视频"><a href="#视频" class="headerlink" title="视频"></a>视频</h1><p>PotPlay64</p>
<h1 id="任务栏透明"><a href="#任务栏透明" class="headerlink" title="任务栏透明"></a>任务栏透明</h1><p>TranslucentTB</p>
<h1 id="系统监控"><a href="#系统监控" class="headerlink" title="系统监控"></a>系统监控</h1><p>XMeters</p>
]]></content>
<categories>
<category>tool</category>
</categories>
<tags>
<tag>software</tag>
</tags>
</entry>
<entry>
<title>fuzzing-basic</title>
<url>/2019/12/04/fuzzing-basic/</url>
<content><![CDATA[<p>fuzzing介绍与afl安装</p>
<a id="more"></a>
<h1 id="0x00-fuzzing简单介绍"><a href="#0x00-fuzzing简单介绍" class="headerlink" title="0x00 fuzzing简单介绍"></a>0x00 fuzzing简单介绍</h1><p>fuzzing:一种通过向程序提供<strong>非预期的输入</strong>并监控输出中的<strong>异常</strong>来发现软件中的<strong>故障</strong>的方法。<br>一般代指模糊测试,一种基于黑盒的测试技术。所谓模糊,是指测试用例是模糊的,不确定的,随机性的。Fuzzing技术本质是依靠随机函数生成<strong>随机测试用例</strong>来进行测试验证,所以是不确定的。</p>
<h2 id="测试用例的产生方式"><a href="#测试用例的产生方式" class="headerlink" title="测试用例的产生方式"></a>测试用例的产生方式</h2><ul>
<li>基于变异:根据已知数据样本通过变异的方法生成新的测试用例。</li>
<li>基于生成:根据已知的协议或接口规范进行建模,生成测试用例。</li>
</ul>
<h1 id="0x01-AFL"><a href="#0x01-AFL" class="headerlink" title="0x01 AFL"></a>0x01 AFL</h1><p>一个基于变异的fuzzer。American Fuzzy Lop简称AFL。</p>
<h2 id="简单介绍"><a href="#简单介绍" class="headerlink" title="简单介绍"></a>简单介绍</h2><p>一个强大的Fuzzing测试工具,在源码编译时进行插桩(简称编译时插桩),可以自动产生测试用例来探索二进制程序内部新的执行路径。</p>
<blockquote>
<p>插桩技术是将额外的代码注入程序中以收集运行时的信息;可以分为两类,</p>
<ul>
<li>源代码插桩(Source Code Instrumentation(SCI)):额外代码注入到程序源代码中。</li>
<li>二进制插桩(Binary Instrumentation(BI)):额外代码注入到二进制可执行文件中。</li>
</ul>
</blockquote>
<h2 id="工作流程"><a href="#工作流程" class="headerlink" title="工作流程"></a>工作流程</h2><p>1) 从源码编译程序时进行插桩,以记录代码覆盖率(Code Coverage);<br>2) 选择一些输入文件,作为初始测试集加入输入队列(queue);<br>3) 将队列中的文件按一定的策略进行“突变”;<br>4) 如果经过变异文件更新了覆盖范围,则将其保留添加到队列中;<br>5) 上述过程会一直循环进行,期间触发了crash的文件会被记录下来。<br><img src="/images/fuzzing-basic/01.jpg" alt="pic01"><br>图片来源与文献[5]</p>
<h2 id="AFL组成"><a href="#AFL组成" class="headerlink" title="AFL组成"></a>AFL组成</h2><p>总共三个部分组成[6]。</p>
<ul>
<li>编译器wrapper<blockquote>
<p>对开源软件编译,编译过程中插入一些AFL识别的函数用以识别探索路径,AFL的编译工具为afl-gcc/afl-g++,afl-clang等。</p>
</blockquote>
</li>
<li>测试器fuzzer<blockquote>
<p>afl-fuzz是AFL重要的主体,用以对软件进行fuzzing。</p>
</blockquote>
</li>
<li>辅助工具<blockquote>
<p>afl-cmin,afl-tmin等,为提升测试的效率和成功率而服务。</p>
</blockquote>
</li>
</ul>
<h2 id="安装"><a href="#安装" class="headerlink" title="安装"></a>安装</h2><p><a href="http://lcamtuf.coredump.cx/afl/" target="_blank" rel="noopener">afl-fuzz官网</a></p>
<blockquote>
<p>环境:ubuntu16.04, afl-2.52b</p>
</blockquote>
<ul>
<li><p>step1: 下载</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">wget http://lcamtuf.coredump.cx/afl/releases/afl-2.52b.tgz</span><br></pre></td></tr></table></figure>
</li>
<li><p>step2: make</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">cd afl-2.52b</span><br><span class="line"># 安装编译环境</span><br><span class="line"># apt install build-essential</span><br><span class="line">make</span><br><span class="line">sudo make install</span><br></pre></td></tr></table></figure>
</li>
</ul>
<p>在命令行中输入<code>afl-</code>,然后使用tab建,可以看到命令提示,表示安装成功。或者<code>afl-fuzz</code>可以看到提示信息。<br>安装后显示如下信息</p>
<p><img src="/images/fuzzing-basic/p5.png" alt="pic"></p>
<h2 id="AFL基本使用"><a href="#AFL基本使用" class="headerlink" title="AFL基本使用"></a>AFL基本使用</h2><h3 id="测试程序"><a href="#测试程序" class="headerlink" title="测试程序"></a>测试程序</h3><p>见参考文献[4]</p>
<h3 id="插桩编译"><a href="#插桩编译" class="headerlink" title="插桩编译"></a>插桩编译</h3><figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">afl-gcc -g -o test test.c</span><br></pre></td></tr></table></figure>
<p>对于其它的编译选项,如make,makefile等编译过程详见参考文献[4]。</p>
<h3 id="开始fuzzing"><a href="#开始fuzzing" class="headerlink" title="开始fuzzing"></a>开始fuzzing</h3><p>建立一个文件夹<code>fuzz_in</code>,里面放入一些文本文件<br>fuzzing命令的格式:</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">afl-fuzz -i testcase_dir -o findings_dir /path/to/program […params…]</span><br><span class="line">afl-fuzz -i testcase_dir -o findings_dir /path/to/program @@</span><br></pre></td></tr></table></figure>
<p>常见参数的含义:</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">-f: 参数表示:testcase的内容会作为afl_test的stdin</span><br><span class="line">-m: 参数表示分配的内存空间</span><br><span class="line">-i: 指定测试样本的路径</span><br><span class="line">-o: 指定输出结果的路径</span><br><span class="line">/dev/null: 使错误信息不输出到屏幕</span><br><span class="line">-t:设置程序运行超时值,单位为 ms</span><br><span class="line">-M:运行主(Master) Fuzzer</span><br><span class="line">-S:运行从属(Slave) Fuzzer</span><br></pre></td></tr></table></figure>
<p>一个示例:<code>afl-fuzz -m 300 -i fuzz_in -o fuzz_out ./test -f</code></p>
<blockquote>
<p>注意,要在目标程序前加上./,否则会报错误。</p>
</blockquote>
<p>成功之后的界面如下:<br><img src="/images/fuzzing-basic/02.png" alt="pic01"></p>
<p>界面分析信息的<a href="http://lcamtuf.coredump.cx/afl/status_screen.txt" target="_blank" rel="noopener">官方参考文档</a>,或者文献[7]<br>一些主要的信息需要注意:</p>
<blockquote>
<ul>
<li>last new path 目标二进制文件或者命令行参数出错,那么其执行路径应该是一直不变的。</li>
<li>cycles done 如果变绿就说明后面即使继续fuzz,出现crash的几率也很低,可以选择在这个时候停止</li>
<li>uniq crashes 代表的是crash的数量</li>
<li>stage progress 正在测试的fuzzing策略、进度、目标的执行总次数、目标的执行速度,如低于500次每秒,那么测试时间就会变得非常漫长。如果发生了这种情况,那么我们需要进一步调整优化我们的fuzzing。</li>
</ul>
</blockquote>
<h3 id="查看crash"><a href="#查看crash" class="headerlink" title="查看crash"></a>查看crash</h3><p>进入设定的输出文件夹,如fuzz_out/crashes。<br>然后复制crash信息,使用命令<code>xxd id:000000,sig:11,src:000001,op:havoc,rep:4</code></p>
<h1 id="0x02-AFLGo"><a href="#0x02-AFLGo" class="headerlink" title="0x02 AFLGo"></a>0x02 AFLGo</h1><h2 id="安装-1"><a href="#安装-1" class="headerlink" title="安装"></a>安装</h2><h3 id="注意事项"><a href="#注意事项" class="headerlink" title="注意事项"></a>注意事项</h3><p><a href="https://github.com/aflgo/aflgo" target="_blank" rel="noopener">官网安装教程</a><br>几点说明:<br>1) 对于官网步骤1:安装<code>llvm</code>环境请看该<a href="https://www.jianshu.com/p/49261b1a50c4" target="_blank" rel="noopener">llvm安装教程</a>,选择<code>llvm6.0.0</code>源码下载(这里有6个软件包需要下载安装)。</p>
<h3 id="报错处理"><a href="#报错处理" class="headerlink" title="报错处理"></a>报错处理</h3><p>我安装make的时候出现如下错误<br><img src="/images/fuzzing-basic/03.png" alt="pic01"><br>此时执行下面的命令就可以可</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">sudo mv /var/lib/dpkg/info/ /var/lib/dpkg/info_old/</span><br><span class="line">$ sudo mkdir /var/lib/dpkg/info/</span><br><span class="line">$ sudo apt-get update</span><br></pre></td></tr></table></figure>
<p>下面这个链接展示了如下在一个<strong>真实开源软件</strong>上进行AFL fuzzing<br><a href="https://github.com/lcatro/Fuzzing-ImageMagick/blob/master/%E5%A6%82%E4%BD%95%E4%BD%BF%E7%94%A8Fuzzing%E6%8C%96%E6%8E%98ImageMagick%E7%9A%84%E6%BC%8F%E6%B4%9E.md" target="_blank" rel="noopener">AFL挖掘ImageMagick漏洞</a></p>
<h1 id="0x03-qysm"><a href="#0x03-qysm" class="headerlink" title="0x03 qysm"></a>0x03 qysm</h1><h2 id="介绍"><a href="#介绍" class="headerlink" title="介绍"></a>介绍</h2><p><a href="https://www.usenix.org/node/217566" target="_blank" rel="noopener">参考论文</a><br>论文摘要</p>
<blockquote>
<p> 最近,有人提出混合模糊方法来解决模糊和协同执行的局限性。这种混合方法已经在各种综合基准测试中显示出了它的有效性,例如DARPA的网络大挑战(CGC)二进制文件,但是它仍然需要在复杂的、真实世界的软件中寻找缺陷。我们观察到,现有共扼执行器的性能瓶颈是其在小规模研究之外被采用的主要限制因素。<br> 为了克服这一问题,我们设计了一个快速的协同执行引擎,称为QSYM,以支持混合模糊。关键思想是使用动态二进制转换将符号模拟与本机执行紧密集成,从而实现更细粒度、更快的指令级符号模拟。此外,QSYM放宽了传统concolic执行者对更好性能的严格可靠性要求,同时利用了一个更快的fuzzer进行验证,为性能优化提供了前所未有的机会,例如,优化地解决约束和修剪无兴趣的基本块。<br> 我们的评估表明,QSYM不仅优于最先进的fuzzers(即bug,发现14×超过VUzzer LAVA-M数据集,钻地,比126年104的二进制文件),但也发现了13个未知安全漏洞在Dropbox轻子等八个实际项目,ffmpeg, OpenJPEG,那些已经被集中测试的最先进的fuzz, AFL OSS-Fuzz。</p>
</blockquote>
<h2 id="安装-2"><a href="#安装-2" class="headerlink" title="安装"></a>安装</h2><ul>
<li>有一个github开源库<a href="https://github.com/sslab-gatech/qsym" target="_blank" rel="noopener">地址</a><br>该开源库中提供了安装方法<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">git clone https://github.com/sslab-gatech/qsym.git</span><br><span class="line">cd qsym</span><br><span class="line"># disable ptrace_scope for PIN</span><br><span class="line">$ echo 0|sudo tee /proc/sys/kernel/yama/ptrace_scope</span><br><span class="line"></span><br><span class="line"># install z3 and system deps</span><br><span class="line">$ ./setup.sh</span><br><span class="line"></span><br><span class="line"># install using virtual env</span><br><span class="line">$ virtualenv venv</span><br><span class="line">$ source venv/bin/activate</span><br><span class="line">$ pip install .</span><br></pre></td></tr></table></figure>
</li>
</ul>
<hr>
<p>遇到了一个错误,再使用<code>virtualenv venv</code>命令地时候<br><img src="/images/fuzzing-basic/04.png" alt="pic01"></p>
<blockquote>
<p>错误原因,系统地python环境是3.5+,需要使用python2.7版本python。</p>
</blockquote>
<p>解决方法:指定python,使用命令<code>virtualenv -p /usr/bin/python venv</code>。这个python指向的是python2.7。更多virtulenv的用法见参考文献[8]</p>
<hr>
<ul>
<li><p>安装成功后会有如下界面<br><img src="/images/fuzzing-basic/p6.png" alt="pic6"></p>
</li>
<li><p>测试<br>首先进入python的虚拟环境</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">source venv/bin/activate</span><br></pre></td></tr></table></figure>
</li>
</ul>
<p>然后运行</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">cd tests</span><br><span class="line">python build.py</span><br><span class="line">python -m pytest -n $(nproc)</span><br></pre></td></tr></table></figure>
<p>可以看到如下界面,表示可以成功运行<br><img src="/images/fuzzing-basic/p7.png" alt="pic6"></p>
<blockquote>
<p>gcc:5.4.0<br>g++:5.4.0</p>
</blockquote>
<h1 id="参考文献"><a href="#参考文献" class="headerlink" title="参考文献"></a>参考文献</h1><p>[1] <a href="https://github.com/secfigo/Awesome-Fuzzing" target="_blank" rel="noopener">https://github.com/secfigo/Awesome-Fuzzing</a><br>[2] <a href="https://github.com/firmianay/CTF-All-In-One/blob/master/doc/5.1_fuzzing.md" target="_blank" rel="noopener">https://github.com/firmianay/CTF-All-In-One/blob/master/doc/5.1_fuzzing.md</a><br>[3] <a href="https://zhuanlan.zhihu.com/p/43432370" target="_blank" rel="noopener">https://zhuanlan.zhihu.com/p/43432370</a> fuzzing技术总结<br>[4] <a href="http://zeroyu.xyz/2019/05/15/how-to-use-afl-fuzz/" target="_blank" rel="noopener">http://zeroyu.xyz/2019/05/15/how-to-use-afl-fuzz/</a> afl使用指南<br>[5] <a href="https://www.freebuf.com/articles/system/191536.html" target="_blank" rel="noopener">https://www.freebuf.com/articles/system/191536.html</a> AFL漏洞挖掘技术漫谈<br>[6] <a href="https://fly8wo.github.io/2018/09/21/AFL-Fuzz%E7%9A%84%E7%AE%80%E5%8D%95%E5%AE%89%E8%A3%85%E4%B8%8E%E7%BC%96%E8%AF%91/" target="_blank" rel="noopener">https://fly8wo.github.io/2018/09/21/AFL-Fuzz%E7%9A%84%E7%AE%80%E5%8D%95%E5%AE%89%E8%A3%85%E4%B8%8E%E7%BC%96%E8%AF%91/</a> 简单安装和编译<br>[7] <a href="https://xz.aliyun.com/t/4314" target="_blank" rel="noopener">https://xz.aliyun.com/t/4314</a> fuzzing简单测试<br>[8] <a href="https://blog.csdn.net/weixin_37773766/article/details/80773590" target="_blank" rel="noopener">https://blog.csdn.net/weixin_37773766/article/details/80773590</a> virtualenv简单介绍</p>
]]></content>
<categories>
<category>Security</category>
</categories>
<tags>
<tag>fuzzing</tag>
<tag>AFL</tag>
</tags>
</entry>
<entry>
<title>latex-basic</title>
<url>/2019/11/29/latex-basic/</url>
<content><![CDATA[<p>latex学习记录</p>
<a id="more"></a>
<h1 id="0x00-学习环境"><a href="#0x00-学习环境" class="headerlink" title="0x00 学习环境"></a>0x00 学习环境</h1><p>使用<a href="https://www.overleaf.com/" target="_blank" rel="noopener">overleaf</a>环境。</p>
<h2 id="中文支持"><a href="#中文支持" class="headerlink" title="中文支持"></a>中文支持</h2><p>两步操作<br>1) menu –> settings –> compile —> 选择XelaTex<br>2) 添加如下</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">\documentclass{article}</span><br><span class="line">\usepackage[UTF8]{ctex}</span><br></pre></td></tr></table></figure>
<h2 id="一个简单的结构如下"><a href="#一个简单的结构如下" class="headerlink" title="一个简单的结构如下"></a>一个简单的结构如下</h2><p>在<code>\documentclass</code>与<code>\begin{document}</code>之间为导言区,设置真篇文档,一般设置页面大小,页眉页脚样式,章节标题样式。</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">\documentclass{article}</span><br><span class="line">\usepackage[UTF8]{ctex}</span><br><span class="line">\begin{document}</span><br><span class="line">main text1中文</span><br><span class="line">\end{document}</span><br></pre></td></tr></table></figure>
<h1 id="0x01基本命令"><a href="#0x01基本命令" class="headerlink" title="0x01基本命令"></a>0x01基本命令</h1><h2 id="命令格式"><a href="#命令格式" class="headerlink" title="命令格式"></a>命令格式</h2><p>以反斜线开头,一般有一下两种格式的命令</p>
<ul>
<li>无参数<br><code>\command</code><br>eg: \songti 我爱latex</li>
<li>有参数<br><code>\command [可选参数]{必选参数}</code></li>
</ul>
<h2 id="常见命令"><a href="#常见命令" class="headerlink" title="常见命令"></a>常见命令</h2><table>
<tr><th>命令</th><th>功能</th></tr>
<tr><td>\chapter</td><td>章</td></tr>
<tr><td>\section</td><td>节</td></tr>
<tr><td>\subsection</td><td>小节</td></tr>
<tr><td>\paragraph</td><td>带题头段落</td></tr>
<tr><td>\centering</td><td>居中对齐</td></tr>
<tr><td>\chapter</td><td>章</td></tr>
<tr><td>\paragraph</td><td>带题头段落</td></tr>
<tr><td>\centering</td><td>居中对齐</td></tr>
<tr><td>\emph</td><td>强调</td></tr>
<tr><td>\verb</td><td>原样输出</td></tr>
<tr><td>\url</td><td>超链接</td></tr>
<tr><td>\footnote</td><td>脚注</td></tr>
<tr><td>\item</td><td>列表条目</td></tr>
<tr><td>\caption</td><td>标题</td></tr>
<tr><td>\includegraphics</td><td>插入图片</td></tr>
<tr><td>\label</td><td>标号</td></tr>
<tr><td>\cite</td><td>引用参考文献</td></tr>
<tr><td>\ref</td><td>引用图表公式等</td></tr>
</table>
<blockquote>
<p>章\chapter应用在\documentclass{book}下面,在\documentclass{article}不能使用</p>
</blockquote>
<h2 id="命令section举例"><a href="#命令section举例" class="headerlink" title="命令section举例"></a>命令section举例</h2><figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">\begin{document}</span><br><span class="line">\section{第一节}</span><br><span class="line">正文</span><br><span class="line">前方高能\footnote{我是注脚}</span><br><span class="line">前方高能\footnote{我是注脚2}</span><br><span class="line">\end{document}</span><br></pre></td></tr></table></figure>
<p><img src="/images/latex-basic/01.png" alt="pic"></p>
<h1 id="0x02-环境"><a href="#0x02-环境" class="headerlink" title="0x02 环境"></a>0x02 环境</h1><h2 id="格式"><a href="#格式" class="headerlink" title="格式"></a>格式</h2><p>无参数</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">\begin{environment}</span><br><span class="line">环境内容</span><br><span class="line">\end{environment}</span><br></pre></td></tr></table></figure>
<p>有参数</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">\begin{environment}[参数]</span><br><span class="line">环境内容</span><br><span class="line">\end{environment}</span><br></pre></td></tr></table></figure>
<h2 id="常见环境"><a href="#常见环境" class="headerlink" title="常见环境"></a>常见环境</h2><table>
<tr><th>环境</th><th>功能</th></tr>
<tr><td>\table</td><td>表格</td></tr>
<tr><td>\figure</td><td>图片</td></tr>
<tr><td>\equation</td><td>公式</td></tr>
<tr><td>\itemize</td><td>无编号列表</td></tr>
<tr><td>\enumerate</td><td>编号列表</td></tr>
</table>
<h2 id="环境举例"><a href="#环境举例" class="headerlink" title="环境举例"></a>环境举例</h2><figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">\begin{document}</span><br><span class="line">\begin{equation}</span><br><span class="line"> a^2-b^2=(a+b)(a-b)</span><br><span class="line">\end{equation}</span><br><span class="line">\end{document}</span><br></pre></td></tr></table></figure>
<p><img src="/images/latex-basic/02.png" alt="pic"></p>
<h2 id="一个简单的文章结构"><a href="#一个简单的文章结构" class="headerlink" title="一个简单的文章结构"></a>一个简单的文章结构</h2><p>latex提供了几个层次结构。<strong>注意</strong>,article中没有<code>chapter</code></p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">\documentclass{article}</span><br></pre></td></tr></table></figure>
<p>其它的如report和book则支持所有的层次。</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">\part{...} %Level -1</span><br><span class="line">\chapter{...} %Level 0</span><br><span class="line">\section{...} %Level 1</span><br><span class="line">\subsection{...} %Level 2</span><br><span class="line">\subsubsection{...} %Level 3</span><br><span class="line">\paragraph{...} %Level 4</span><br><span class="line">\subparagraph{...} %Level 5</span><br></pre></td></tr></table></figure>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">\title{杂谈勾股定理}</span><br><span class="line">\author{张三}</span><br><span class="line">\date{\today}</span><br><span class="line"> \bibliographystyle{plain}</span><br><span class="line"> </span><br><span class="line">\begin{document}</span><br><span class="line"> \maketitle</span><br><span class="line"> \tableofcontents</span><br><span class="line"> </span><br><span class="line">\section{勾股定理在古代}</span><br><span class="line">\section{勾股定理的近代形式}</span><br><span class="line"></span><br><span class="line">\bibliography{math}</span><br><span class="line">\end{document}</span><br></pre></td></tr></table></figure>
<p>编译之后显示的文件如下:<br><img src="/images/latex-basic/03.png" alt="pic02"></p>
<h1 id="参考文献"><a href="#参考文献" class="headerlink" title="参考文献"></a>参考文献</h1><p>[1] <a href="https://github.com/tuna/thulib-latex-talk" target="_blank" rel="noopener">https://github.com/tuna/thulib-latex-talk</a><br>[2] <a href="https://liam.page/2014/09/08/latex-introduction/" target="_blank" rel="noopener">https://liam.page/2014/09/08/latex-introduction/</a><br>[3] <a href="https://github.com/huangxg/lnotes" target="_blank" rel="noopener">https://github.com/huangxg/lnotes</a> 雷太赫排版系统</p>
]]></content>
<categories>
<category>tool</category>
</categories>
<tags>
<tag>latex</tag>
</tags>
</entry>
<entry>
<title>buileSite-ref</title>
<url>/2019/11/27/buileSite-ref/</url>
<content><![CDATA[<p>建立本站参考的文章</p>
<a id="more"></a>
<p>环境</p>
<blockquote>
<p>git<br>node.js<br>next v.7.4.0主题</p>
</blockquote>
<p>[1] <a href="http://theme-next.iissnan.com/getting-started.html" target="_blank" rel="noopener">http://theme-next.iissnan.com/getting-started.html</a><br>大致流程,命令<br>[2] <a href="https://www.cnblogs.com/liuxianan/p/build-blog-website-by-hexo-github.html" target="_blank" rel="noopener">https://www.cnblogs.com/liuxianan/p/build-blog-website-by-hexo-github.html</a><br>个性化配置教程<br>[3] <a href="https://leomalik.github.io/hexo%E7%9A%84next%E4%B8%BB%E9%A2%98%E4%B8%AA%E6%80%A7%E5%8C%96%E9%85%8D%E7%BD%AE%E6%95%99%E7%A8%8B.html" target="_blank" rel="noopener">https://leomalik.github.io/hexo%E7%9A%84next%E4%B8%BB%E9%A2%98%E4%B8%AA%E6%80%A7%E5%8C%96%E9%85%8D%E7%BD%AE%E6%95%99%E7%A8%8B.html</a></p>
<p>添加背景图片<br>[4] <a href="https://bufsnake.github.io/hexo-next-7-xx%E6%B7%BB%E5%8A%A0%E8%83%8C%E6%99%AF%E5%9B%BE%E7%89%87.html" target="_blank" rel="noopener">https://bufsnake.github.io/hexo-next-7-xx%E6%B7%BB%E5%8A%A0%E8%83%8C%E6%99%AF%E5%9B%BE%E7%89%87.html</a></p>
<p><a href="https://asphelzhn.github.io/2018/12/19/hexo/" target="_blank" rel="noopener">https://asphelzhn.github.io/2018/12/19/hexo/</a></p>
<p><a href="https://buptccq.top/%E7%94%A8hexo%E6%90%AD%E5%BB%BA%E4%B8%AA%E4%BA%BA%E5%8D%9A%E5%AE%A2.html" target="_blank" rel="noopener">https://buptccq.top/%E7%94%A8hexo%E6%90%AD%E5%BB%BA%E4%B8%AA%E4%BA%BA%E5%8D%9A%E5%AE%A2.html</a></p>
]]></content>
</entry>
<entry>
<title>hbase-base01</title>
<url>/2019/11/25/hbase-base01/</url>
<content><![CDATA[<p>hbase基本知识</p>
<a id="more"></a>
<p>HBase是一个高可靠,高性能,面向列,可伸缩的分布式数据库,google的BigTable开源实现,主要用来存储非结构化和半结构化的松散数据。</p>
<blockquote>
<p>学习版本:HBase1.4</p>
</blockquote>
<p>该版本的hadoop版本要求见官网<a href="https://hbase.apache.org/book.html#basic.prerequisites" target="_blank" rel="noopener">版本要求</a><br><a href="https://hbase.apache.org/book.html#getting_started" target="_blank" rel="noopener">官方参考文档</a></p>
<h1 id="0x00下载安装"><a href="#0x00下载安装" class="headerlink" title="0x00下载安装"></a>0x00下载安装</h1><h2 id="安装"><a href="#安装" class="headerlink" title="安装"></a>安装</h2><ul>
<li>step1:从官网下载hbase-1.4.11-bin.tar.gz版本的文件。解压缩<code>tar -zxvf hba.....</code></li>
<li>step2(可选):为了能够方便使用hbase命令,在/etc/profile中配置环境变量<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">export PATH=/opt/hadoop-2.7.1/bin:/opt/hbase-1.4.11/bin:${PATH}</span><br></pre></td></tr></table></figure>
</li>
</ul>
<p>使用命令<code>source /etc/profile</code>使之生效。</p>
<blockquote>
<p>环境变量配置在<code>~/.bashrc</code>中也可以。</p>
<ul>
<li>step3:如果所属用户不是root,此时还需要修改hbase文件的权限。</li>
<li>step4:通过命令<code>hbase version</code>可以验证是否安装成功,即可查看吧版本信息。<br><img src="/images/hbase-basic/01.png" alt="pic1"></li>
</ul>
</blockquote>
<h2 id="伪分布式模式配置"><a href="#伪分布式模式配置" class="headerlink" title="伪分布式模式配置"></a>伪分布式模式配置</h2><p>hbase有三种模式,单机模式使用本地文件系统存储数据,伪分布式和分布式采用HDFS存储数据。<br>参考文献[1]有具体配置方法</p>
<h3 id="配置hbase-env-sh。"><a href="#配置hbase-env-sh。" class="headerlink" title="配置hbase-env.sh。"></a>配置<code>hbase-env.sh</code>。</h3><ul>
<li>配置JAVA_HOME</li>
<li>配置HBASE_CLASSPATH<br>设置为本机hadoop安装目录下的conf目录。<br>eg:<code>export HBASE_CLASSPATH=/opt/hadoop-2.7.1/etc/hadoop</code></li>
<li>配置HBASE_MANAGES_ZK<br><code>export HBASE_MANAGES_ZK=true</code>表示hbase自己管理zookeeper,不需要单独zookeeper。</li>
</ul>
<h3 id="配置hbase-site-xml"><a href="#配置hbase-site-xml" class="headerlink" title="配置hbase-site.xml"></a>配置<code>hbase-site.xml</code></h3><p>设置<code>hbase.rootdir</code>指定HBase数据的存储位置,即在HDFS上的路径<br>设置<code>hbase.cluter.distrubuted</code>为true。</p>