-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex.xml
More file actions
1800 lines (1660 loc) · 159 KB
/
index.xml
File metadata and controls
1800 lines (1660 loc) · 159 KB
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" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>sin-coder</title>
<link>https://sin-coder.github.io/</link>
<description>Recent content on sin-coder</description>
<generator>Hugo -- gohugo.io</generator>
<language>en-us</language>
<lastBuildDate>Fri, 24 Apr 2020 19:55:33 +0800</lastBuildDate>
<atom:link href="https://sin-coder.github.io/index.xml" rel="self" type="application/rss+xml" />
<item>
<title>Linux文本处理命令总结</title>
<link>https://sin-coder.github.io/linux/text/</link>
<pubDate>Fri, 24 Apr 2020 19:55:33 +0800</pubDate>
<guid>https://sin-coder.github.io/linux/text/</guid>
<description>一、概述 Linux中的有关文本处理和分析的命令有很多,本节主要介绍几个使用比较频繁的命令:
grep、sed、find、awk。其中每个命令的使用方式都是比较灵活的,命令的参数很多,选
项也很多,但我们只需记住些常用的即可
二、grep 1、用途简介 grep用于查找文件中符合条件的字符串,比较多地用于日志行为分析
2、命令格式 grep match_pattern file
3、常用参数 -o:只输出匹配的文本行
-v:只输出没有匹配的文本行
-c:统计文件中包含文本的行数
-n:打印匹配的行号
-i:搜索时忽略大小写
-l:只打印文件名
-e:指定字符串作为查找文件内容的样式
-r:递归的搜索
4、使用示例 (1)匹配多个字符串模式
grep -e &quot;mode1&quot; -e &quot;mode2&quot; filename
(2)在多级目录中对文本递归搜索
grep &quot;mode&quot; . -r -n
(3)在当前目录下查找以file为后缀的文件名并且包含test字符串的文件
grep test file
(4)在日志文件夹中查找包含docker字符串的日志
grep -n docker /var/log/log
三、sed 1、用途简介 sed命令主要是利用脚本来处理文本文件,主要用来自动编辑一个或多个文件、简化</description>
</item>
<item>
<title>TiDB-调度原理简介</title>
<link>https://sin-coder.github.io/database/tidbschedu/</link>
<pubDate>Fri, 24 Apr 2020 00:53:48 +0800</pubDate>
<guid>https://sin-coder.github.io/database/tidbschedu/</guid>
<description>一、TiKV概述 TiKV是TiDB的数据库的分布式存储引擎,数据以Region为单位进行复制和管理,每个
Region为单位进行复制和管理
每个Region会有多个Replica,这些Replica会分布在不同的TiKV节点上,其中leader负
责读和写,Follower负责同步Leader发过来的Raft log
二、关键问题 如何保证同一个Region的多个Replica分布在不同的节点上?一台机器上启动多个TiKV 的实例存在的问题?
TiKV集群进行跨机房部署用于容灾的时候,如果一个机房掉线,如何保证不会丢失Raft Group的多个Replica?
添加一个节点进入TiKV集群之后,如何将其他节点的数据搬过来?
如果一个节点短暂掉线时如何处理,如果节点长时间掉线,如何处理?
如何调接Replica副本的个数
并不是所有的Region都被经常访问,可能热点数据只在少数的几个Region上
集群在做负载均衡的时候,需要搬迁数据,这种数据的迁移能否不占用大量的网络带
宽、磁盘IO和CPU
三、系统调度需求 1、分布式高可用存储系统的要求 副本数量不能多也不能少
副本需要分布在不同的机器上
新增加节点之后,其他节点上的副本如何迁移过来
节点下线时,需要将该节点的数据迁移走
满足这些需求后系统具有多副本的容错、动态的扩容/缩容、容忍节点掉线和自动故
障恢复的功能
2、需要优化的需求 整个集群leader的均匀分布
维持每个节点的存储容量均匀
维持热点分布均匀
管理节点的状态,手动上线/下线节点、自动下线失效节点
满足这些需求后,系统的负载更加均匀,且更加方便的管理
四、系统调度的方案 满足3.</description>
</item>
<item>
<title>TiDB-存储原理简介</title>
<link>https://sin-coder.github.io/database/tidbstorage/</link>
<pubDate>Fri, 24 Apr 2020 00:53:20 +0800</pubDate>
<guid>https://sin-coder.github.io/database/tidbstorage/</guid>
<description>一、数据存储的要求 1、数据库应该怎么存储数据 数据库最根本的功能就是把数据存下来,保存数据的方法有很多
(1)直接使用数组 最简单的就是在内存中直接构建一个数据结构(比如可以使用一个数组),保存用户
发来的数据。这个方案非常简单,性能也是非常好的。但是存在很大的缺点:数据完全在
内存中,一旦停机或者服务重启,数据就永远丢失
(2)数据丢失如何解决 为了解决数据丢失的问题,可以将数据存储在非易失性的介质中,比如硬盘这时我们
可以在磁盘上创建一个文件,收到一条数据就在文件中Append一行,这样持久化存储
数据
(3)磁盘出现故障如何解决 为了防止磁盘出现坏道,我们可以做RAID,单机冗余存储
(4)单机出现故障如何解决 但是如果机器挂了呢?我们还可以将存储改为网络存储,或者是通过硬件或者软件
进行存储复制,数据安全了
2、数据存储的其他需求 跨数据中心的容灾
写入速度如何提高
数据保存下来后是否方便读取
保存的数据如何修改,如何支持并发的修改
原子性地修改多条记录
二、TiKV的设计思想 1、TiKV的数据存储模型 TiDB是Key-Value的模型,并且提供有序遍历的方法,TiKV的主要特点就是:
TiKV可以看做一个巨大的Map
这个Map中的Key-Value是按照Key的二进制顺序有序排列的
我们可以找到某一个Key的位置,然后不断的调用Next方法以递增的顺序获取比这
个Key大的Key-Value。这里的存储模型和SQL中的Table无关,TiKV是一个巨大的分
布式Map
2、TiKV数据的持久化机制 TiKV没有选择直接向磁盘上写数据,而是将数据保存在RocksDB中,具体的数据落
地由RocksDB完成。RocksDB是一个非常优秀的开源的单机存储引擎,通过使用它TiKV
已经实现了高效可靠的本地存储
但是如何保证单机失效的情况下,数据不会丢失和出错,所以我们需要将数据复制
到多台机器上,这样一台机器挂了,在其他机器上还有副本,,所以还需要一个可靠,
高效且能处理副本失效的情况
3.TiKV的一致性设计思想-优化的Raft算法 Raft的主要就是一个一致性的协议,主要的功能是Leader选举、成员变更、日志复制</description>
</item>
<item>
<title>TiDB-计算原理</title>
<link>https://sin-coder.github.io/database/tidbcompute/</link>
<pubDate>Fri, 24 Apr 2020 00:53:05 +0800</pubDate>
<guid>https://sin-coder.github.io/database/tidbcompute/</guid>
<description>一、关系表到KV存储的映射 1、原理 TiDB的存储引擎是一个全局有序的分布式Key-Value引擎TiDB对于每一个表分配一
个TableID,每一个索引都会分配一个IndexID,每一行分配一个RowID,TableID在整个集
群中唯一,IndexID/RowID在表内唯一,这些ID都是int64类型
2、具体实现 (1)每行数据按照如下规则进行编码 Key:tablePrefix{tableID}_recordPrefixSep{rowID} Value:[col1,col2,col3,col4] #tablePrefix和recordPrefixSep都是特定的字符串常量 #用于在KV空间中 区分其他的 (2)Unique Index数据的编码 Key:tablePrefix{tableID}_indexPrefixSep{indexID}_indexedColumnsValue (3)对于非Unique Index的编码 可能有多行数据的ColumnsValue一样,所以应该这样去编码:
Key:tablePrefix{tableID}_indexPrefixSep{IndexID}_indexedColumnsValue_rowID Value:null #Key里面的Prefix都是字符串常量,作用都是区分命名空间, #以避免不同类型数据之间的相互冲突 每一个Table内部的所有Row都有相同的前缀,一个Index的数据也是有相同的数据的
所以可以非常方便的将Row或者Index数据有序的保存在TiKV中,即一个表中的所有Row
数据就会按照RowID的顺序排列在TiKV的Key空间中,某一个Index的数据也会按照Index
的顺序排列在Key空间内
3、元信息的管理 Database/Table都有元信息,就是表的定义和各项属性,这些信息需要持久化的存
储在TiKV中,每个Database/Table都被分配了一个唯一的ID。这个ID作为唯一的标识,
并且在编码为Key-Value,这个ID都会编码到Key中。这样可以构造出一个Key信息,
Value存储的是序列化后的元信息。除此之外,还有一个专门的Key-Value来存储当前
的Schema信息
二、TiDB的整体结构 1、TiKV Cluster 主要的作用就是作为KV引擎存储数据
2、TiDB Servers 这一层就是无状态的节点,本身并不会去存储数据,节点之间完全对等;TiDB
Server这一层主要是处理用户的请求,执行SQL逻辑运算
三、SQL层运算 TiDB将SQL查询映射为KV的查询,再通过KV的接口获取对应的数据
1、查询方案的简介 以select count(*) from user where name = &quot;TiDB&quot;为例</description>
</item>
<item>
<title>TiDB架构原理简介</title>
<link>https://sin-coder.github.io/database/tidbinfr/</link>
<pubDate>Fri, 24 Apr 2020 00:52:37 +0800</pubDate>
<guid>https://sin-coder.github.io/database/tidbinfr/</guid>
<description>一、TiDB主要特性 TiDB是一个开源分布式关系型数据库,它主要用来应用在全部的OLTP的场景和大部
分的OLAP场景。TiDB作为一个开源的分布式数据库主要有以下特点:
1、高度兼容MySQL MySQL迁移到TiDB是非常容易的,无论是单机迁移还是集群的迁移
2、支持无限的水平弹性扩展 新增节点实现TiDB的水平扩展,轻松地应对高并发、海量数据的场景
3、强一致性和高可用 基于Raft的多数派选举协议可以提供100%的数据强一致性,可以实现故障的自动恢复
4、分布式事务 支持ACID事务
TiDB这些特性使它成为业界认可的优秀数据库产品,但是我们要想深入理解这些特性,
还要从架构原理的角度学习
二、TiDB的架构原理简介 TiDB集群主要包括三个核心组件:TiDB Server,PD Server,TiKV Server
具体的架构原理图如下所示:
1、TiDB Server TiDB Server 负责接收SQL请求,处理SQL相关的逻辑,并通过PD找到存储计算所需
数据的TiKV地址,与TiKV交互数据,最终返回结果。
TiDB Server 是无状态的,其本身并不存储数据,只负责计算,可以无限水平扩展,
可通过负载均衡的组件(LVS、HAProxy或者F5)对外提供统一的接入地址
2、PD Server(Placement Driver) PD是整个集群的管理模块,具体的工作职能是:
存储这个集群的原信息(某个Key具体存储在哪个TiKV的节点)
对TiKV集群进行调度和负载均衡(数据迁移、Raft Group leader)
分配全局唯一且递增的事物ID
PD通过Raft协议保证数据的安全性,Raft的leader Server负责处理所有操作,其余的PD
Server仅用于保证高可用性。一般情况下建议部署奇数个节点
3、TiKV Server TiKV Server是TiDB中的数据存储引擎,存储的数据的基本单位是Region</description>
</item>
<item>
<title>Linux文件系统目录结构</title>
<link>https://sin-coder.github.io/linux/filesys/</link>
<pubDate>Fri, 24 Apr 2020 00:45:56 +0800</pubDate>
<guid>https://sin-coder.github.io/linux/filesys/</guid>
<description>一、Linux文件系统目录概述 Linux下的文件系统为树形结构,入口为 / (根目录)。树形结构下的文件目录,具体如
下图所示,不同的Linux发行版有较大差异,但是主体的目录都是比较相似的
二、具体目录功能简介 1、 / (根目录) 这是文件系统的统一入口,是最高一级的目录
2、/bin和/sbin 这些目录下存放着可执行文件的链接,基础系统所需的命令位于此目录,如cp、chmod、
ls等命令;对于/bin下的命令任何用户均可执行或者配置,但是/sbin下的命令,普通用户无
权限执行该目录下的命令
3、/boot 这里存放Linux内核以及系统引导程序,你可以看到grub文件夹(常见的开机引导程序),
千万不懂乱动这些文件
4、/dev dev即是device,这里存放着所有的设备文件,Linux中所有的东西都是以文件的形式
存在的,也包括硬件设备,比如说硬盘、U盘、鼠标等设备
5、/etc 存放系统程序或者一般工具的配置文件
6、/lib 系统程序所需要的所有共享库文件、类似于Windows平台下的共享库DLL文件
7、/lost+found 系统以外崩溃或者机器意外关机时,在该目录下产生一些文件碎片;在系统启动时,
文件系统会检查这里,尝试修复破损的文件系统
8、/media 即插即用型存储设备的挂载点自动在这个目录下创建,比如USB盘系统自动挂载后
或者CDROM自动挂载后便会在这个目录中创建一个目录
9、/mnt media文件夹是系统自动挂载设备的地方,而这个目录是用户手动挂载设备的地方
比如可以将dev文件夹中的设备通过命令挂载到mnt的目录进行操作的
挂载是由操作系统使一个存储设备上的计算机文件和目录可供用户通过计算机的文件
系统访问的一个过程。Windows系统中的挂载通常指给磁盘分区分配一个盘符,想当于打开
一个文件系统的入口;Linux系统的挂载是指将一个设备,挂接到一个已存在的目录上,Linux
操作系统将所有的设备都看作文件,它将整个计算机的资源整合成一个大的文件目录,要想
访问存储设备中的文件,必须将文件所在的分区挂载到一个已经存在的目录上了,然后通过
这个目录来访问存储设备
常用的命令就是:
mount [-参数] [设备名称] [挂载点] 对应的解挂命令就是umonut
10、/opt options可选择,有些软件的安装包也会被安装在这里,比如Chrome浏览器等软件包</description>
</item>
<item>
<title>Linux系统性能分析命令总结</title>
<link>https://sin-coder.github.io/linux/perfcommand/</link>
<pubDate>Fri, 24 Apr 2020 00:43:15 +0800</pubDate>
<guid>https://sin-coder.github.io/linux/perfcommand/</guid>
<description>一、概述 操作系统的资源主要包括以下几种:CPU、内存、硬盘IO、网络IO,熟练地对这些资
源的使用进行分析可以帮助我们排查一些服务器使用过程中遇到的问题
二、CPU使用分析 1、CPU性能指标简介 CPU使用时间主要分为用户态时间、系统态时间和空闲态时间,分别表示CPU处于用
户态执行的时间、系统内核执行的时间和空闲系统进程执行的时间,三者之和就是CPU的
总时间。
当用户没有用户进程和系统进程需要执行的时候,CPU就执行系统缺省的空闲进程,
CPU的利用率就是指非空闲进程占用时间的比例,即CPU执行非空闲进程 / CPU总的执行
时间
CPU方面的主要性能指标如下几项:
CPU的使用率
上下文切换
运行队列长度
下面分别介绍几个CPU的性能指标
1、CPU_IDLE CPU_IDLE就是基于/proc/stat计算出来的,运行cat /proc/stat后的结果如下:
可以看出cpu的核数,比如cpu0-cpu7便是表是系统有8个核,截取cpu0的参数
如下:cpu0 32736 0 51047 48473626 33879 0 142 0 0 0,这些参数含义分别为:
user(32736) 系统从启动开始累计到当前时刻,用户态的CPU时间,不包含nice值为负 的进程
nice(0) : 系统从启动开始累计到当前时刻,nice值为负的进程所占用的CPU时间
sysytem(51047) 系统启动开始累计到当前时刻,内核时间
IDLE(48473626) 从系统启动开始累计到当前时刻,除IO等待时间以外其它等待时间</description>
</item>
<item>
<title>常见的排序算法总结</title>
<link>https://sin-coder.github.io/datastructure/sort/</link>
<pubDate>Sat, 04 Apr 2020 23:04:00 +0800</pubDate>
<guid>https://sin-coder.github.io/datastructure/sort/</guid>
<description>经典排序算法的总结 之前总是听一些大牛说学会了排序就相等于学会了算法,能手写个快速排序基本就能通过面试了,这一
点我是很不理解的;后来慢慢地发现这是有道理的,常见的几种排序算法中蕴含了许多经典的算法思想,
比如说递归、分治、迭代、双指针、空间换时间等,算法的问题很多,但是计算机处理问题的方式却只
有那一种。所以要归根溯源,从简单的排序算法中去学习算法思想也是一种很有效的方法
一、算法描述 对一个无序的数组进行排序 (从小到大或者从大到小)
二、算法分类标准 划分排序算法的主要标准有稳定性、内外排序、时空复杂度、是否比较排序等
1.稳定性 如果数组中有两个元素是相等的,在经过某个排序算法之后,原来前面的那个元素仍然在另一个元素的
前面,那这个排序算法就是稳定的;相反如果在原来两个相等元素中前面的一个元素被移到了后面,那就
是不稳定的
2.内外排序 内排序是所有的排序操作都在内存中完成;
外排序是由于数据太大,因此把数据放入磁盘中,排序需要经过磁盘和内存的数据传输才能进行
3.是否比较排序 比较排序: 一个算法在排序的过程中使用比较操作来判断两个元素的大小关系,那么这个算法
就是比较排序,常见的排序算法都是比较排序算法,比如冒泡排序、插入排序、堆排序,这些排序
算法的平均时间复杂度最快也只能是O(nlogn)
非比较排序比较典型的算法有计数排序、桶排序和基数排序,这类排序的时间复杂度可以达到
O(n)的级别
4.时空复杂度 就是时间复杂度和空间的复杂度了
三、常见的排序算法 1.冒泡排序(Bubble Sort) (1)算法描述:冒泡排序是将相邻元素进行比较,大数慢慢地沉底,小数放置到前面
(2)算法特点:
内排序,所有操作在原来的数组中就可以完成了,不需要额外的空间
时间复杂度是O(n^2),空间的复杂度是O(1)
稳定排序: 如果两个元素的位置相同,他们的位置是不会进行交换的
(3)代码实现
#冒泡排序 Python的版本 def bubble_sort(nums): n = len(nums) for i in range(n): for j in range(1,n-i): if nums[j] &lt; nums[j-1]: nums[j-1],nums[j] = nums[j],nums[j-1] return nums //冒泡排序 Java版本 private void swap(int[] nums,int i,int j){ int temp = nums[i]; nums[i] = nums[j]; nums[j] = temp; } public void bubbleSort(int[] nums){ for(int i = nums.</description>
</item>
<item>
<title>服务器并发模型的总结</title>
<link>https://sin-coder.github.io/post/server/</link>
<pubDate>Wed, 26 Feb 2020 15:59:05 +0800</pubDate>
<guid>https://sin-coder.github.io/post/server/</guid>
<description> 服务器常用并发模型 1.单线程同步模型 单线程同步模型是最简单的服务器模型,每次只能处理一个客户端的连接,其他连接必须要等到前面的
连接关闭后才能得到服务器的处理,否则发过来的请求会悬挂住,没有任何响应;服务端是串行地处理客
户端的连接的
一个客户端必须要等到另外一个客户端运行结束后才可以运行,这也太慢了吧
2.多线程同步模型 服务器可以并行地处理多个客户端的连接,没来一个连接就开启一个新的线程单独进行处理,每个线程
都是同步读写客户端的连接的
3.多进程同步模型 Java使用者很少能够体会多进程的魅力,他们都是使用多线程。但是在Python中并不常见,因为Python
的GIL只能使单个进程占满一个CPU核心,多线程不能利用多核的优势,所以Python服务器可以使用多进程
模型
4.PreForking同步模型 进程在操作系统中是非常耗资源的,所以要对服务器开辟的进程数量进行限制,避免系统的负载过重,
这就是多进程PreForking模型。
这种模型预先产生多个子进程,共同对服务器套接字竞争资源,但是最终只能有一个进程获取到。
如果并行的连接数超过了prefork的数量,那么后来的客户端请求将会阻塞。但是这样也可以通过子进程
的单线程同步模型改成多进程同步模型的方式解决
5.单进程异步模型 上述的服务器模型都是同步的,而现代的服务器一般都是异步的,效率是比较高的,它是一种非阻塞的
服务器模型,实现了对进程和线程的解放,再加上事件轮询机制的配合使得它的性能比同步高出了许多
像Nignx、Nodejs、Redis都是基于异步模型构建出来的,性能非常高
6.PreForking 异步模型 单进程的IO并发能力有限,虽然使用了事件轮询和异步读写功能,但是还不能应对高并发的需求,所以
需要使用多进程,这样也可以对我们的CPU最大限度的利用
开源的Tornado服务器和Nignx就是采用了多进程PreForking模型达到了超高并发的处理能力
</description>
</item>
<item>
<title>Redis中的RPC协议结构</title>
<link>https://sin-coder.github.io/post/redisrpc/</link>
<pubDate>Mon, 24 Feb 2020 16:59:37 +0800</pubDate>
<guid>https://sin-coder.github.io/post/redisrpc/</guid>
<description>Redis中的RPC协议结构 Redis的客户端和服务器之间进行RPC通信时,使用的是其开发者专门设计的文本通讯协议RESP。它的
开发者认为数据库系统的性能瓶颈一般不在于网络流量,而是数据库自身内部的逻辑处理上。所以Redis使
用了浪费流量的文本协议。但是,依然可以取得很高的访问性能
下面主要介绍RESP协议的相关内容
一、RESP协议简介 RESP(Redis Serialization Protocol),就是Redis的序列化协议,这是一种对人友好的文本协议。它将
传输的结构数据分为5种最下单元的类型,单元结束时统一加上回车换行符\r\n,具体如下
单行字符串以+符号开头
+hello world\r\n 多行字符串以$符号开头,后跟字符串的长度
$11\r\nhello world\r\n #长度加上字符串 整数值以:符号开头,后跟整数的字符串形式
:1024\r\n 错误的消息以 - 开头
-WRONGTYPE Operation against a key holding the wrong kind of value\r\n 数组以*开头,后面跟数组的长度
*3\r\n:1\r\n:2\r\n:3\r\n #先是数组长度,依次再是每个内容,表示数组[1,2,3] NULL用多行字符串表示,不过长度要写成-1
$-1\r\n 空串用多行字符串表示,长度填0
$0\r\n\r\n #两个\r\n之间隔的是空串 客户端向服务器发送指令使用多行字符串数组,比如一个简单的set指令 set author codehole会被序列化为
下面的字符串
*3\r\n$3\r\nset\r\n$6\r\nauthor\r\n$8\r\ncodehole\r\n 服务端向客户端回复的响应要支持多种数据结构,基本上都是上述5种基本类型的组合
#单行字符串响应 &gt;set author codehole OK #这里的OK就是单行响应,没有使用引号括起来 #错误响应 -ERR .</description>
</item>
<item>
<title>分布式RPC设计思想</title>
<link>https://sin-coder.github.io/post/ditrirpc/</link>
<pubDate>Mon, 24 Feb 2020 15:59:05 +0800</pubDate>
<guid>https://sin-coder.github.io/post/ditrirpc/</guid>
<description>分布式RPC设计思想 分布式所要解决的问题就是当系统中的个别节点发生故障后整个系统依然能够稳定的对外提供服务,对于
RPC框架来说同样也是;多线程和多进程解决的都是并发的问题,无论怎样都只能算是单点的设计,要想保证
系统的高可用性,分布式的设计必不可少。下面就介绍一些RPC框架设计中关于分布式的一些思想
一、客户端连接池 如果RPC的服务端部署在多个节点上时,客户端得出的是一个服务列表,有多个IP端口对,客户端的
连接池可以随机挑出任意的RPC服务节点进行连接,而且每个服务节点都应该有个权重值,如果所有节点
的权重值一样时,它们的流量分配就是均匀的,如果每个节点的权值较小,它被客户端选中的概率也会比
较小。设计示例代码如下:
class RPCNode{ String addr; //服务端的地址 int weight; //节点权重 } class RPCCluster{ RPCNode[] nodes; //节点的列表 Node random(); //按权重随机挑选节点 } 二、容灾 Failover 如果有一个服务节点挂掉时,客户端需要采取一定的策略避免请求失败,比如可以重试,但是不能进行无
线的重试,要有一定的重试策略
一个可行的方案是当节点挂掉时,将失效的节点摘除,放置的失效的节点列表中;然后每隔一段时间检查
失效的节点是否恢复了,如果恢复了,那就从失效的节点中移出,重新加入有效节点的列表中;当然也不能仅
依据一次的检测就判断节点是否有效,可以通过检测一个时间段内的出现的错误数量判断,如果错误数量过多
那就说明了真的失效了,这也是为了避免部分网络问题的原因
三、降权法 我们可以为每个服务端节点赋一个权值,改变权值就可以改变节点的相对流量了;如果某个节点出现了一次
错误就对该节点进行降权,错误次数越多,降权降得越快,最终可以到达一个最小值,但是无论如何,每个节
都还有翻身的机会。被降权的节点只要有一次调用成功,权值就会恢复正常
一个非常简单的策略就是当服务端节点错误时进行权重减半,比如从1024开始减半,一直到1,当恢复时
可以进行权重翻倍
四、服务发现 如果服务端可以支持动态扩容,那么它的稳定性和高可用性就会更高。当系统的负载比较高的时候,我们
可以通过添加节点的方式减轻压力。但是就像前面设计的静态RPC服务地址列表,当节点增加时,必须要修改
客户端的配置重启才能生效,但是生产环境怎么可能重启配置这时候服务发现的技术就上台了
服务发现技术就是服务裂变变更时,客户端可以快速地收到这些信息,从而调整自己的工作状态,这样无
需进行重启就可以完成服务的扩容和缩容
示例代码如下:
class ServiceDiscovery(object): def register_service(self,name,addr): pass def get_services(self,name): pass def on_services_changed(self,name): pass 服务发现技术依赖于服务之间中间节点,它接受服务的注册、提供服务的查找、以及服务列表变更的实时</description>
</item>
<item>
<title>RPC框架中的消息传递和协议</title>
<link>https://sin-coder.github.io/post/rpcjiaohu/</link>
<pubDate>Sun, 23 Feb 2020 14:22:56 +0800</pubDate>
<guid>https://sin-coder.github.io/post/rpcjiaohu/</guid>
<description>RPC框架中的消息传递和协议 RPC是两个子系统之间进行的直接信息交互,它使用操作系统提供的套接字来作为消息的载体,以特定
的消息格式来定义消息的内容和边界;客户端和服务端都是通过文件描述符的读写API来访问操作系统内核
中的网络模块为当前的套接字分配的发送(send buffer)和接收(recv buffer)缓存
具体在这个过程中消息的内容是什么就需要我们深入RPC的协议进行学习了
协议设计的整体思想 对于一串消息流,我们必须能确定消息边界,提取出单条消息的字节流片段,然后对这个片段按照一
定的规则进行反序列化来生成相应的消息对象;消息的表示就是序列化后的消息字节流在直观上的表现
形式,文本的形式对人类比较友好,二进制的形式对计算机比较友好
每个消息都有其内部字段的结构,结构构成了消息内部的逻辑规则,程序要按照结构的规则来决定字段
序列化后的顺序
一、消息边界 RPC需要在一条TCP链接上进行多次消息传递,在连续的两条消息之间必须有明确的分隔符规则,以便
接受端可以将消息分割开来;基于TCP连接之上的单条消息如果过大,就会被网络协议栈拆分成多个数据包
进行传送,而如果消息过小,协议栈就有可能将多个消息合成一个数据包进行发送。对于接收端来说,它看
到的只是一串串的字节数组,如果没有明确的消息边界规则,接收端就不知道这一串字节数组包含了多少消息
比较常用的两种分割方式是特殊分隔符法和长度前缀法,分别如下图所示
特殊符分割法就是在每条消息的末尾追加一个特殊的分隔符,并且保证消息中间的数据不能包含特殊分
割符。比如最常见的分隔符是“ \r\n ”,当接受端遍历字节数组时发现了“\r\n”,就可以确定这个分隔符之前的
字节数组是一条完整的消息。在HTTP和Reids协议中就大量了使用“\r\n”分隔符,这种应用场景要求消息体的
内容是文本消息
这种方法的优点是消息的可读性比较强,可以直接看到消息的文本内容,但是不适合传递二进制消息,
因为二进制的字节数组中很容易出现“\r\n”分隔符的ASCII值,如果非要传递的话需要对二进制进行base64
编码转换成文本消息再进行传送
消息发送端在每条消息的开头再增加4字节长度的整数值,标记消息体的长度,这样消息的接受者就会
首先读取长度信息,然后再读取相应长度的字节数组就可以将一个完整的消息分离出来,常用于二进制消息
这种方法的优缺点与特殊分割符法正好相反。长度前缀法可读性很差,但是适用于二进制协议,但是
对于文本和内容都可以进行传递
HTTP协议是上述两种法的混合型协议,因为HTTP的消息头采用的是纯文本外加“\r\n”分隔符,而消息
体是通过消息头中的Content-length的值来决定长度的。HTTP协议可以传输文本协议,也可以传输二进制
数据,比如常见的音视频图像,所以被称为超文本传输协议
二、消息结构 每条消息都有着包含它的语义结构信息,有些消息协议的结构信息是显示的,还有些是隐式的。JSON
消息的结构就可以直接通过它的内容体现出来,可读性非常高,但是它有太多的冗余信息,比如每个字符
串都使用双引号界定边界,键值对之间必须有冒号进行分割,对象之间必须使用大括号进行分割;而且连
续的多条json消息即使结构完全一样,仅是value值不同,也需要发送同样的key字符串
消息的结构在同一条消息通道上是可以进行复用的,比如建立在链接的开始的RPC的客户端和
服务端之间先互相告知消息的结构,后续发送消息时只需要按照这个消息的模板发送消息就可以了,
接收端会自动将value值与相应位置的key关联起来,这样的模式可以节省比较多的流量</description>
</item>
<item>
<title>RPC框架中客户端的实现</title>
<link>https://sin-coder.github.io/post/distri_client/</link>
<pubDate>Fri, 21 Feb 2020 16:08:30 +0800</pubDate>
<guid>https://sin-coder.github.io/post/distri_client/</guid>
<description>RPC框架中客户端的实现 RPC客户端实现的难点在于客户端一般都不是单线程的,需要考虑在多线程的情况下如何流畅的使用客
户端而不会出现并发的问题,交互过程的模型图如下:
就如上面的模型图所示,在多线程的客户端中,客户端与数据库之间会维护一个连接池。当线程中的代码
需要访问数据库时,先从数据库中获取一个连接,与数据库交互完成后再将这个连接归还给线程池。所以对
于业务线程来说,拿到的连接不会同时被其他的线程所共享,这样就可以避免并发的问题
此外,服务器的性能往往随着并发连接数量的增加而下降,所以必须严格控制有效连接的数量;连接池的
数量上限也是数据库的一层壁垒,下面将介绍一些客户端设计中的主要机制
一、安全锁 连接池是为多线程而设计的,每个线程都会访问线程池的对象,所以线程池需要使用锁来控制数据结构
的安全。安全锁会使线程安全,但是也会导致性能受损。锁的临界区代码要尽量避免耗时的计算和I/O操作,
而且锁的粒度还要尽可能的细,但是代码实现不易
增大锁的粒度可能在某些程度上使代码实现更为容易,因为连接都是用来进行相对缓慢的I/O操作的,锁
是基于内存操作的,相比于I/O操作可以忽略不记
二、懒惰连接 连接池的连接多为懒惰连接,在需要的时候才会向数据库中申请。因为一个系统非常闲置,以前开辟了
太多的连接是对资源的浪费;懒惰的连接池可以保证只会对单线程的程序开辟一个连接
当然懒惰连接也有不好的地方,比如服务器的代码需要经过一个热身的过程,早来的请求需要额外付出
一次建立连接的耗时代价、如果数据库连接参数不正确,需要在收到用户的请求进行显式数据访问时才能发现
三、健康检查和性能追踪 连接池中管理的连接可能或因为网络原因而损坏断开连接,连接池需要保持内部管理的连接是健康可用
具体实现的机制如下:
线程从连接池中申请连接返回之前,线程池需要对连接进行检查,确定连接是通常的
线程将连接归还给连接池时,线程池对连接进行检查,确定连接没有被搞坏
线程池定时对管理的连接进行检查
如果检查发现连接有问题时,一般的做法两种:
抛弃当前的连接连接池的连接数量减1,如果是在线程的borrow方法中,那就再重新去连接池申请一个
修复当前连接,一般也就是执行重连
此外,好的连接池还应该考虑到性能的可追踪性,当用户通过线程池分配的连接去访问数据库时,
它的消息执行时间应该是可以被统计和追踪的。所以连接池往往还需要对原生的连接进行一定程度的
包装,在关键的函数代码调用前后增加性能统计代码,并对外提供监听端口,以便将统计信息传递给
外部的监控模块
四、超时策略 当业务线程繁忙的时,连接池内部的连接可能会出现不够用的场景,一个线程请求的borrow方法
在长时间的等待后仍然等不到空闲的连接,这就是超时问题,主要有以下是3种解决方案:
永不超时,等不到就一直接着等 一定的时间拿不到后,就像外部抛出超时异常,中断业务逻辑 如果发现连接池没有空闲连接,就去申请一个新的连接给调用方。当调用方归还连接的时候,连接池计算当前 缓存的连接数量,如果超过了最大的连接数,就将当前的连接销毁,否则就保存</description>
</item>
<item>
<title>搭建自己的VPN服务器实现科学上网</title>
<link>https://sin-coder.github.io/post/skipwall/</link>
<pubDate>Thu, 20 Feb 2020 22:31:32 +0800</pubDate>
<guid>https://sin-coder.github.io/post/skipwall/</guid>
<description>搭建自己的VPN服务器实现科学上网 最近不知道怎么了,自己原先够买的VPN服务莫名其妙的无法使用了,自己部署在github上的网站也无
法访问了,这日子真的过不下去了,VPN不断地被墙也不是一天两天的事了。因此自己便一直想着能否搭建
自己的VPN服务,只供自己使用被墙的风险不就是大大降低了嘛!
在写这篇博客之前,自己也想到一个笑话,在Git问世之前,Linux社区的开发人员由于私自破解由
BitMover开发的版本控制软件,致使BitMover公司收回了Linux社区对版本控制软件的使用权。本来觉
得由Linux之父Linus之父向BitMover公司道个谦,这事就过去了,可实际上是不可能的。大神终究是大神
,Linus自己花了两周的时间就用C写了一个分布式的版本控制系统,就是Git,之后Linux的内核代码已经
开始由Git进行管理了。所以对于技术领域而言,哪里有压迫,哪里就有反抗
好了,废话少说,进入正题
一、前期准备 要想搭建一个专属VPN服务来实现翻墙,首先必须要有一台海外的服务器(香港的也可以),否则你服
务的流量也出不去啊!那么问题来了,国内的云服务商对于海外的服务器卖的还都是挺贵的,恐怕经济上
难以承受。那有没有白嫖的海外服务器呢,有!请看下图
百度的广告有时还是挺好的,让我发现了AWS还提供免费的云主机服务,但是哪有天上掉馅饼的,提供免费
服务的前提是你要先注册吧,注册的时候竟然需要VISA或者Master的卡号(就是那种能付美元的银行卡了),这
种卡我还真的没有。然后发现某宝上有卖卡号的,自己就去买了一个(大概30元,相比于VPN的费用算是便宜了)
。注册使用银行卡号不是需要扣费,而是需要检测银行卡中是否有剩余的1$,从而验证卡号的可用性
在这里简要说明一下,AWS为每个用户提供了每月750小时的运行实例时间,持续12个月。也就是说我们
在一个账户上可以运行多个虚拟机的实例,总共时间不能超过750个小时,这足够我们持续使用一年的了
二、创建虚拟主机 1.切换地理区域 在具体创建实例之前,需要将区域设置为东京(推荐,网络延迟最小),当然也可以设置为其他的地区
2.创建实例 选择EC2服务后就可以开始创建实例了,可以看到免费套餐中可选的系统类型是比较多的,Linux的各种
版本、Windows Server等,这里我们就选用推荐的第一个吧(放在第一个肯定有它的理由)。选择第一个进
入即可
然后是选择一个实例类型,审核并启动即可,其他的先不需要配置
点击启动后,会有一个创建密钥对的界面,这里选择创建新的密钥对即可,再输入密钥对名称后一定注意要
下载保存密钥对(非常重要,不然你用客户端就登不上去了),之后选择启动实例即可;
启动完成后点击实例号即可进入虚拟机控制台界面,注意这时我们需要关注的虚拟机信息: 公有DNS,
这个就相当于这台虚拟机的公网地址,由于IP地址经常会变动,所以可以用公有DNS来指向IP地址,实现
一个动态的绑定
那么这时我们可以ping通这个ip地址吗?来试一下,可以发现是ping不同的
具体原因就是我们还未对虚拟机的安全策略配置,它是拒绝被ping的。我们进入安全组,编辑入栈规则,
添加一条放通规则保存即可
这时我们再进行ping测试,就发现可以ping通了
三、连接虚拟主机 这里我们使用MobaXterm客户端连接虚拟机,其他工具像Xshell、Putty客户端均可,在新建会话中,将刚才</description>
</item>
<item>
<title>RPC的简介和使用</title>
<link>https://sin-coder.github.io/post/intro_rpc/</link>
<pubDate>Wed, 19 Feb 2020 16:08:30 +0800</pubDate>
<guid>https://sin-coder.github.io/post/intro_rpc/</guid>
<description>RPC的简介和使用 一、RPC出现的背景 当单台服务器无法满足用户的请求,就需要多台服务器联合起来构成一个集群共同对外提供一个服务,这
也是我们常说的分布式。同时业务服务或随着产品需求的增多愈发变得臃肿,架构上必须进行服务的拆分,一
个完整的大型服务会分成许多独立的小服务,每个小服务都会有独立的进程去管理对外的提供服务,这就是我
们常说微服务
当用户请求到来的时候,需要将其分散到多个服务去各自的处理,然后又需要将这些子服务的结果汇总
起来呈现给用户。那么服务之间如何进行交互?这就是RPC要解决的问题
二、什么是RPC? RPC(Remote Procedure Call)即远程过程调用,是分布式系统中一中常见的通信方法。当然除了RPC
外,常见的多系统数据交互方案还有分布式消息队列、HTTP请求调用、数据库和分布式缓存。如下图
其中可以明显的看到RPC和HTTP调用都是没有经过中间件的,它是端到端系统的直接数据交互。关于
RPC和HTTP的主要区别接下来会阐述
三、RPC的应用 RPC是分布式系统进行通信的基础,像Nignx/Redis/MuSQL/Dubbo/Spark/Tensorflow都是基于RPC技术
发展起来的,似乎每一个分布式的软件或者系统实现上都有它的身影
Nginx和后端服务之间的交互本质上属于RPC数据的交互 Hadoop的文件系统HDFS中NameNode和多个DataNode之间通过二进制的RPC协议通讯 TensorFlow Cluster的RPC的通讯框架使用了Google自研的gRPC框架 四、HTTP和RPC的区别与联系 HTTP1.0协议时,HTTP的调用还只是短链接调用,一个请求来回之后连接就会关闭。HTTP1.1在HTTP
1.0协议的基础上进行了改进,引入了KeepAlive特性可以保持HTTP连接长时间不会断开,以便在同一个连接
上进行多次连续的请求,使的HTTP进一步地接近了RPC
当HTTP进化到2.0版本时,Google开源了一个建立在HTTP2.0协议上的RPC框架:gRPC, 这时的HTTP
和RPC之间已经没有明显的界限了。
所以我们可以将HTTP看成一种特殊的RPC
五、广义上的RPC 在分布式系统中我们经常使用的数据库、消息队列和缓存本质上也可以看成RPC技术的一种应用,比如
像下面的分布式数据库模型图:
可以看出子系统和数据库时间的交互也是通过RPC进行的,只不过这里是三个子系统之间进行的交互,
而且这里的数据库是具备主从复制功能的数据库。一般情况为了提升系统的性能,都会使用这种主从读写
分离的数据库。一个业务系统将数据写往主库,主库再将数据同步到从库,然后另一个业务子系统又从库
里将数据取出来</description>
</item>
<item>
<title>分布式一致性</title>
<link>https://sin-coder.github.io/post/consistency/</link>
<pubDate>Mon, 17 Feb 2020 08:04:41 +0800</pubDate>
<guid>https://sin-coder.github.io/post/consistency/</guid>
<description>分布式一致性概述 一、什么是分布式一致性 1.CAP 理论 对于分布式一致性,最直观的理解就是分布式系统中的不同节点不能产生矛盾。比较著名的理论就是
CAP Theorem,即在一个分布式系统中,不能同时满足以下三点:一致性(Consistency)、可用性
(Availability)、分区容错性(Partition Tolerance)
一致性(C):在分布式系统中的所有数据备份,同一时刻是否有同样的值
可用性(A):在集群中一部分节点故障后,集群整体能否响应客户端的读写请求
分区容忍性(P):大多数的分布式系统都分布在多个子网络,每个网络都叫做一个区,分区容错的意思即是
区间通信可能失败;比如一个分布式系统有5个节点,有3个在美国,有两个在中国,这就是两个区
它们之间可能无法通信
CAP原则的核心就是只能实现AP、CP、AC,不会存在CAP,从上图中也可以看到典型的一些数据库
产品也只是满足了CAP的部分特性
2.一致性模型 (1)弱一致性(最终一致性)
关于弱一致性,通俗的解释就是当一个节点向数据库写入数据时,其他的节点可能无法立即读到该数据,
但是它们最终一定会读到该数据,下面是一些典型的实例
DNS (Domain Name System)
Gossip(Cassandra 的通讯协议)
(2)强一致性
对于分布式系统的容错性最关注的问题就是数据不能存储在单个的节点上,一般的解决方案就是state
machine replication(状态机复制共识算法),具体的实现算法有以下几种:
同步
Paxos
Raft(multi-paxos)
ZAB(multi-paxos)
二、强一致性算法 1.主从同步 主从同步复制的工作过程如下,Master接受写请求、Master复制日志到slave、Master等待,直到
所有从库返回;但是这样存在一个问题:一个节点失败,Master阻塞,导致整个集群不可用,保证了
一致性,但是可用性却大大降低了
解决上述问题的方法:多数派的算法,每次写都保证写入大于N/2个节点,每次读保证从大于N/2个</description>
</item>
<item>
<title>Docker 镜像详解</title>
<link>https://sin-coder.github.io/post/docker-image/</link>
<pubDate>Sun, 02 Feb 2020 22:17:53 +0800</pubDate>
<guid>https://sin-coder.github.io/post/docker-image/</guid>
<description>Docker 镜像详解 镜像是Docker三大核心概念中最为重要的。Docker运行容器前需要本地存在对应的镜像,如果镜像不
存在,Docker会从Docker Hub中下载,当然用户也可以配置自定义的镜像仓库
关键问题 使用pull命令从Docker Hub中下载镜像到本地 查看本地已有的镜像信息、管理镜像标签 使用search命令在远端仓库进行搜索和过滤 删除镜像标签和镜像文件 创建用户定制的镜像并保存为外部文件 向Docker Hub仓库中推送自己的镜像s 一、获取镜像 docker [image] pull NAME[:TAG] #直接从Docker Hub镜像源来下载镜像 其中 [] 中的内容为可选项,NAME为镜像仓库名称(用来区分镜像),TAG为镜像的标签,一般用来
表示版本信息,描述一个镜像需要“名称+标签”;如果不显式地指定TAG,则默认会选择latest标签,会下
载仓库中的最新镜像。不过,镜像的仓库名称中还应该添加仓库地址(即注册服务器)作为前缀,默认情
况下使用官方的Docker Hub服务(前缀可以忽略的),如果从非官方的仓库下载,则必须指定完整的仓库
地址
从下载镜像的过程中,可以看到镜像文件一般是由若干层组成的,Docker下载中会获取并输出镜像
的各层信息,每一层都有一个简写的唯一id。当不同的镜像包括相同的层时,本地仅存储了层的一份内
容,这样可以减少存储空间
$ docker pull ubuntu Using default tag: latest latest: Pulling from library/ubuntu 5c939e3a4d10: Pull complete c63719cdbe7a: Pull complete 19a861ea6baf: Pull complete 651c9d2d6c4f: Pull complete Digest: sha256:8d31dad0c58f552e890d68bbfb735588b6b820a46e459672d96e585871acc110 Status: Downloaded newer image for ubuntu:latest docker.</description>
</item>
<item>
<title>Python之美</title>
<link>https://sin-coder.github.io/program/beauty/</link>
<pubDate>Sat, 01 Feb 2020 16:08:30 +0800</pubDate>
<guid>https://sin-coder.github.io/program/beauty/</guid>
<description>Python之美 新建一个Python文件,写入下面语句 &quot;import this&quot; 执行下看看发生了什么
终端会打出这样的信息:
The Zen of Python, by Tim Peters
Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.</description>
</item>
<item>
<title>容器技术的前世今生</title>
<link>https://sin-coder.github.io/post/%E5%AE%B9%E5%99%A8%E6%8A%80%E6%9C%AF%E7%9A%84%E5%8F%91%E5%B1%95/</link>
<pubDate>Sat, 01 Feb 2020 03:23:01 +0800</pubDate>
<guid>https://sin-coder.github.io/post/%E5%AE%B9%E5%99%A8%E6%8A%80%E6%9C%AF%E7%9A%84%E5%8F%91%E5%B1%95/</guid>
<description>容器技术的前世今生 概述 什么是容器,在Docker官方网站中,特地地对这个名词进行了定义,容器是一个标准化的软件单元。
进一步的解释为容器是打包代码及其所有依赖项的软件的标准单元,它将软件和其运行环境隔离开来,
因此应用程序可以从一个计算环境快速可靠地运行到另一个计算环境。
可以说Docker是当今最知名的容器平台之一,它于2013年开源,但是容器化和隔离的技术却有很长
的历史,了解这部分的历史将有助于我们对容器技术的理解
容器发展简史 1979年,Unix7在开发过程中引入了Chroot Jail和Chroot系统调用,它允许用户将进程及其子进程与操作 系统的其余部分隔离开来。但是这种隔离未考虑安全机制,根进程可以轻松地退出chroot
那问题便来了,chroot jail是什么,jail为监狱的意思,似乎要把什么东西锁起来。在类UNIX的操作系统
上,默认的根目录均为“ / ”,而chroot的作用就是改变正在运行的进程及它的子进程的根目录。例如,将某
个程序的根目录从原先的默认的系统根目录更改为“ /home/ ”,则这个/home目录就变成了这个程序的逻辑
根目录,与此同时,这个被修改了根目录环境的程序就不能再进入这个逻辑根目录之外的路径了。所以这就
相当于限制某个程序能进入的目录树,称为监狱也是情有可原了
2000年,FreeBSD Jail被引入到FreeBSD OS中,旨在为简单的Chroot文件隔离带来更多的安全性,此 外FreeBSD还实现了将进程及其活动隔离到文件系统的特定视图中(不懂,暂时略过)
2001年,Linux VServer被推出,它使用了类似chroot的机制与“安全上下文”及操作系统虚拟化来提供虚 拟化解决方案,相比于chroot进步了许多,允许在单个Linux发行版(VPS)上运行多个Linux的发行版
VPS (Virtual Private Servers) :虚拟专用服务器
2004年,Oracle推出了Solaris Containers,这是一个用于X86和SPARC处理器的Linux-VServer版本 Solaris Containers是由系统资源控制和“区域”提供的边界隔离组合而成
SPARC是一套RISC(精简指令集)架构
2005年,OpenVZ推出,它和Linux-VServer一样,使用操作系统级虚拟化,但是这样有一定的限制,容器 共享相同的体系结构和内核版本,当客户需要不同于主机的内核版本时就有点力不从心了;而且
OpenVZ未将一些用于创建隔离的控制机制的补丁集成到内核中
2007年,Google发布了CGroups,这是一种机制,它能限制和隔离一系列进程的资源使用(如:CPU、 内存、磁盘I/O和网络等),而且被集成到了Linux内核中</description>
</item>
<item>
<title>Learn Docker with a picture</title>
<link>https://sin-coder.github.io/post/docker%E5%85%A5%E9%97%A8%E5%AD%A6%E4%B9%A0/</link>
<pubDate>Sat, 01 Feb 2020 03:22:01 +0800</pubDate>
<guid>https://sin-coder.github.io/post/docker%E5%85%A5%E9%97%A8%E5%AD%A6%E4%B9%A0/</guid>
<description> 一张图入门Docker 关于Docker我们在云计算、虚拟化基础概念和容器技术的前世今生两篇文章中已经介绍过其应用的场景
和优点,在本篇文章我们将学习Docker的一些基础概念和用法,话不多说,赶紧上图
Docker三大基础概念:镜像、容器和仓库 一、镜像(Image) 镜像就类似于我们使用Virtual Box或者VMware创建虚拟机之前需要下载的系统镜像文件,比如iso文件、
img文件之类的都称为镜像文件。我们可以将Docker镜像理解为一个面向Docker引擎的只读模板,它自身即
包含了文件系统
镜像与容器的关系就类似于印钞模板与钞票之间的关系,当然我们可以通过Dockerfile来制作自己的镜像。
制作好的镜像可以被封装在一个盒子中(保存为tar文件),当需要在另一个环境中使用镜像时,只需将盒子
搬过去,重新取出(Load)镜像即可。当然这些比喻并不十分严格,只是帮助理解而已。
通过版本管理和增量的文件系统,Docker提供了一套十分简单的机制来创建和更新现有的镜像。用户在
对容器进行修改并提交(commit)后,重新运行依然可以保持这个变化
有关Docker镜像的操作详解,请参看Docker入门学习--镜像
二、容器(Container) 容器是从镜像创建的运行实例,可以将其启动(run)、开始、停止和删除,而且这些容器都是相互隔离
的,互相不可见的。用户可以将容器看做一个简易版的Linux系统环境(包括root用户权限、进程空间、用户
空间和网络空间),以及运行在其中的应用程序打包而成的应用盒子
镜像本身是可读的,容器从镜像启动的时候,Docker会在镜像的最上层创建一个可写层,镜像本身并没
有发生改变
有关Docker镜像的操作详解,请参看Docker入门学习--容器
三、仓库(Repository) Docker仓库类似于代码的仓库,是Docker集中存放镜像文件的场所。Docker利用仓库来管理镜像,这
种设计理念与Git十分相似。用户可以直接从仓库中拉取(pull)镜像来供自己使用,也可以将自行制作镜像
并上传(pull)到仓库中,等到在另外一台机器上使用该镜像时,再pull下来即可
Docker仓库和注册服务器(Registry)不是同一个概念,注册服务器是存放仓库的地方,其上往往存
放着多个仓库。每个仓库集中存放某一类的镜像,这些镜像通过Tag进行区分。
根据所存储镜像的公开与否,Docker仓库可以分为公开仓库和私有仓库。Docker Hub是目前最大的公
开仓库;当然Docker也支持用户在本地的网络内创建 一个只能自己访问的仓库
有关Docker镜像的操作详解,请参看Docker入门学习--仓库
当然Docker的内容远不止这些,接下来会 一 一 介绍
</description>
</item>
<item>
<title>云计算和虚拟化基础概念简介</title>
<link>https://sin-coder.github.io/post/%E4%BA%91%E8%AE%A1%E7%AE%97%E5%92%8C%E8%99%9A%E6%8B%9F%E5%8C%96%E6%8A%80%E6%9C%AF/</link>
<pubDate>Fri, 31 Jan 2020 19:21:17 +0800</pubDate>
<guid>https://sin-coder.github.io/post/%E4%BA%91%E8%AE%A1%E7%AE%97%E5%92%8C%E8%99%9A%E6%8B%9F%E5%8C%96%E6%8A%80%E6%9C%AF/</guid>
<description>云计算和虚拟化基础概念 一、虚拟化 虚拟化技术是一种资源管理优化技术,它是将计算机的各种物理资源(CPU、内存、磁盘、网卡)
等I/O设备予以抽象、转换,然后呈现出来一个可供分割并任意组合为一个或多个(虚拟)计算机的配置
环境。虚拟化技术打破了计算机内部实体结构间不可切割的障碍,使得用户以比原来更好的方式来应用
这些计算机的硬件资源。
虚拟化是一个广义的术语,具体可细分为以下三种:
平台虚拟化(Platform Virtualization):操作系统级别的虚拟化
资源虚拟化(Resouce Virtualization):特定系统资源的虚拟化,如CPU、内存、存储或者网络等
应用程序虚拟化(Applocation Virtualization) :仿真、模拟和解释技术等,如Java虚拟机
二、虚拟机 虚拟机是一台计算机转换为多台计算机的基于物理硬件的抽象。虚拟机管理程序允许多个虚拟机
在单台计算机上运行,它可以创建虚拟化硬件,其中包括虚拟磁盘、虚拟网络接口、虚拟CPU等,同
时它还具有可以与此虚拟硬件通信的内核。每个虚拟机都包含着操作系统、应用程序,这些文件可能
占用数十GB的存储空间。管理程序可以进行托管,这就意味着它是可以在主机操作系统上运行的软件、
还可以运行在裸机上,即直接在机器硬件上运行,替换真实的操作系统。
虚拟机可以分为系统虚拟机或者是过程虚拟机,我们通常所说的是系统虚拟机,它是通过主机硬件
来模拟整个操作系统的;而“进程虚拟机”是用于模拟执行单个进程的编程环境的,Java虚拟机便是这样
三、容器 1.问题背景 在过去的几年中,让运维人员最为头疼就是需要为各种迥异的开发语言安装相应的运行环境。
但是Docker的横空出现解决了这一问题,Docker提供了让开发工程师可以将应用和依赖封装到一
个可移植的容器中的能力,这种集装箱式的封装方式,让运维人员和开发人员都能够以Docker所
提供的镜像分发的标准化方式发布应用,打破了异构语言在团队中形成的壁垒
2.容器简介 容器是包含应用程序代码、配置和依赖关系的软件包;它是通过在操作系统级别进行虚拟
化来使应用程序可移植,从而创建基于内核的隔离的封装系统。容器化运行的应用程序可以放在
任何地方,消除了依赖关系
当然,作为独立的单元,容器能够在任何操作系统,如Linux、Mac、甚至像Windows这样
的非UNIX系统中运行。容器还可充当标准化的工作或者计算单元,比如每个容器运行单个Web
服务器、数据库的分片或者单个Spark工作程序,只需要扩展容器的数量就能够便捷地扩展应用
每个容器都有一个固定的资源配置(CPU、内存、线程数),并且扩展应用程序只需要扩展
容器的数量即可。容器也是实现微服务架构的一个很好的工具,每个微服务只是一组协作容器
3.容器和虚拟机的区别 容器和虚拟机具有相似的资源隔离和分配优势,但具体功能不同,因为容器虚拟化了操作系统,
而不是硬件;容器的创建和停止十分迅速,而且对自身资源的需求十分有限,远远低于虚拟机,很
很多时候直接把容器当做应用本身也是没有任何问题的。传统意义上如果说在一台主机上运行一百
个虚拟机那肯定是天方夜谭,可是一台主机运行上千个容器却已经成为了现实
二者关键性能的区别如下表格:
容器和虚拟机架构的区别:</description>
</item>
<item>
<title>消息队列简介</title>
<link>https://sin-coder.github.io/post/messagequ/</link>
<pubDate>Tue, 28 Jan 2020 01:22:22 +0800</pubDate>
<guid>https://sin-coder.github.io/post/messagequ/</guid>
<description>消息队列简介 一、消息队列简介 1.概述 消息是指在应用间传送数据,消息可以只包含文本字符串、或者包含嵌入式对象。
消息队列是一种应用程序对应用程序的通信方法。它是是生产者-消费者模型的一个典型的代表,一端往消息
队列中不断地写入消息,而另一端则可以读取队列中的消息。这样发布者和接受者都不知道对方的存在。
消息队列也可以简单理解为:把要传输的数据放在队列中
2.消息获取模式 消费者获取消息时有两种模式,点对点模式和发布订阅模式
(1)点对点模式 点对点模型通常是一个基于拉取或者轮询的消息传递模型,这种模型从队列中请求消息,而不是将消息推送
到客户端。这种模式的特点是一对一,发送到队列的消息被一个且只有一个接受者接收处理,即使有多
个消息监听者也是如此,消息被收到后即可清除
点对点模式的优点是队列发送数据和客户端接收数据的速度是相匹配的,缺点是客户端需要实时监控队列中
是否有消息存在
(2)发布/订阅模式 发布订阅模型是一个基于推送的消息传送模型,该种模型下订阅者有临时订阅者和持久订阅者之分,临时订
阅者只在主动监听主题时才接收消息;而持久订阅者则监听主题的所有消息,即使当前订阅者不可用,
处于离线状态。这种模型的特点是一对多,数据生产后,推送给所有的订阅者
发布/订阅模式的优点是客户端不需要实时监控队列中是否有消息存在,缺点是队列发送数据的速度无法和多
个客户端接收数据的速度是相匹配
二、消息队列作用 解耦:客户端与客户端之间或者客户端和服务器 之间不需要直接连接,而是通过中间件来进行连接。而且允许你 独立的扩展或修改两边的处理过程,只要确保它们遵守同样的接口约束
冗余:消息队列可以对数据进行持久化(本地备份)直到它们已经被处理,这样就规避了数据的丢失。许多消息 队列均采用“插入-获取-删除”的范式,即在把一个消息从队列中删除之前,需要你的系统明确的指出该消息已
经被处理完毕
峰值处理:可以组建集群,进而增大消息入队和处理的频率。在访问量剧增的情况下,应用仍然需要继续发挥作 用,但是这样的突发流量并不常见。如果为以能处理这类峰值访问为标准来投入资源随时待命无疑是巨大的
浪费。消息队列基于它的可扩展性使其本身可以顶住突发的访问压力,而不会因为突发的超负荷的请求而使
系统完全崩溃
数据可恢复:当系统的一部分组件失效时,不会影响到整个的系统 。消息队列降低了进程间的耦合度,即使一个 处理消息的进程挂掉,加入队列中的消息仍可在系统恢复后被处理
顺序保证:消息队列本来就是排好序的,并且也能够保证数据按照特定的顺序来进行处理
缓冲:消息队列可以控制和优化数据流经过系统的速度,解决生产消息和消费消息的处理速度不一致的情况</description>
</item>
<item>
<title>Git&Github 学习笔记</title>
<link>https://sin-coder.github.io/post/git/</link>
<pubDate>Mon, 27 Jan 2020 00:52:28 +0800</pubDate>
<guid>https://sin-coder.github.io/post/git/</guid>
<description>一、版本控制 1.版本控制工具的功能 协同修改:多人互不影响地修改服务器端的同一个文件
数据备份:不仅要保存文件的当前状态,还能够保存每一个提交过的历史状态
版本管理:在保存每一个版本的文件信息时,能够做到不保存重复的数据,节省存储空间,提高运行效率;
SVN采取的是增量式管理的方式,Git采取了文件系统快照的方式
权限控制:对团队中参与开发的人员进行权限控制,Git还可以对团队外开发者贡献的代码进行审核
历史记录:查看修改人、修改时间、修改内容、日志信息;将本地文件恢复至某一个历史状态
分支管理:允许开发团队在工作过程中多条生产线同时推进任务,提高效率
2.常见版本控制工具 (1)集中式版本控制工具:CVS、SVN、VSS等
集中式的版本控制中每个开发者是一个客户端,文件和版本信息存储在服务端,开发者们都直接与
服务器进行交互,集中式的版本控制具有单点故障的问题
(2)分布式版本控制工具:Git、Mercurial、Bazaar等
分布式版本控制相比于集中式最大的优点就是能够避免单点故障的问题
二、Git 简介 1.Git的发展历史 Git是一个免费、开源的分布式版本控制工具。在2005年,由Linus基于C语言开发完成,开发的初衷是
管理Linux社区中提交的代码, 而这位Linus正是是开发Linux系统内核的大神,它的个人语录也是我的座右铭
&quot;Talk is cheap, Show me the Code&quot;,少废话我只看代码。
2.Git的特性简介 从Git的图标中就可以看到分支是其最引以为傲的特点,实际上Git的优点还有很多
大部分操作在本地完成版本控制,不需要联网
对数据进行完整性保证,基于Hash算法
尽可能添加数据而不是删除或者修改数据
与Linux命令全面兼容,这个当然了,都是由Linus开发的
3.Git 的结构 Git的本地结构图</description>
</item>
<item>
<title>分布式系统学习笔记</title>
<link>https://sin-coder.github.io/post/distri/</link>
<pubDate>Mon, 27 Jan 2020 00:44:13 +0800</pubDate>
<guid>https://sin-coder.github.io/post/distri/</guid>
<description>一、分布式系统概述 1.什么是分布式系统? 分布式系统主要由网络、分布式存储与分布式计算等部分构成的,分布式存储侧重于数据的读写存取及一致性等方面,而分布式计算则侧重于资源、任务的编排和调度
2.分布式系统的特点 没有强制性的中心控制、次级单位具有自治的特质、次级单位之间彼此高度链接、点对点之间的影响通过网络形成了非线性的因果关系
3.传统架构面临的难题: 系统的扩展 高并发的访问要求我们的后端系统架构弹性且可扩展
三维扩展:
X轴扩展:水平复制,即在负载均衡服务器后增加多个Web服务器,
Y轴扩展:对数据库的扩展,即进行分库分表,分库是将关系紧密的表放在一台数据库服务器上,分表是因为一张表的数据太多,需要将一张表的数据通过hash放在不同的数据库服务器上
Z轴扩展:业务方向的扩展,才能将巨型应用分解为一组不同的服务,将应用进一步分解为微服务
4.CAP定理
在分布式系统中,系统的一致性(Consistency)、可用性(Availability)、分区容忍性(Partion tolerance)。这三者不能同时保证,由于网络通信的不确定性,分区的容忍性是必须要保证的,而且互联网应用比企业级应用更加偏向于保持可用性,通常用最终一致性代替传统事务的ACID强一致性
二、分布式计算 1.概述 分布式计算核心的思路就是系统架构无单点,让整个系统可以扩展。分布式计算环境下的节点分为有状态存储节点和无状态存储节点。
无状态存储节点,不存储数据,请求分发可以采取很简单的随机算法或者是轮询的算法就可以了,如果需要增加机器,则只需要把对应的运算代码部署到一些机器上然后启动起来,引导流量到那些机器即可实现动态的扩展了。简单来说就是某台机器承担了某种角色后,能够快速的广播给需要这个角色提供服务的机器。
而针对有状态节点,扩容难度较大,因为每台Server中均有数据,所以请求分发的算法不能够随机或者轮询,一般来说常见算法就是哈希或者使用Tree来做一层映射,增加机器时需要经历一个复杂的数据迁移过程------》自动化扩容和迁移的工具
2.数据处理的发展过程
GFS-------------》HDFS
BigTable--------》HBase
MapReduce----》MapReduce
(Hadoop技术栈)
MapReduce(离线处理)-----》Spark(高性能批处理技术)------》Storm(流处理)----》Flink
3.批处理(Batch Processing)与流处理(Stream Processing) 主要区别:每一条数据在到达时是被处理的(流处理),还是作为一组新数据的一部分稍后进行处理(批处理)
批处理:在批处理中新到达的数据元素被收集到一个组中,整个组在未来的时间内进行处理。至于何时处理每个组可以选择多种方式来确定,可以基于预定的时间间隔(如每隔5分钟)、或者在某些触发的条件下(只要包含5个元素/拥有超过1MB的数据)。传统的数据仓库和Hadoop就是专注于批处理的。批处理示意图如下:
缺点:具有延迟性、新数据的到达与该数据的处理之间的延迟将取决于直到下一批处理窗口的时间
流处理:流处理设计的目的是为了在数据到达时对其进行响应,这就要求它们实现一个由事件驱动的体系架构,也可以说是在系统的内部工作流在接收到数据后立即连续监视新数据和调度处理。
应用:Flink、Beam等都支持“流式处理优先,将批处理视为流式处理的特殊情况”,但是流式处理器的出现并没有让批处
理器变得过时。因为纯流式处理系统在批处理工作负载时其实是非常慢的。
Apache Beam: 这样统一的API通常会根据数据是持续的(无界)、还是固定的(有界)将工作负载委托给不同的
运行机制
Flink: 提供的流式API,可以处理有界或者无界的场景,同时任然提供了单独的DataSet API用于批处理
三、分布式调度 1.概述
经典资源调度器(Yarn)-----》数据调度(Data Placement)、资源任务调度(Resource Management)、计算调度(Application Manager)、本地微(自治)调度
2.资源调度</description>
</item>
<item>
<title>同步/异步、阻塞/非阻塞辨析</title>
<link>https://sin-coder.github.io/post/syn/</link>
<pubDate>Sun, 26 Jan 2020 21:35:45 +0800</pubDate>
<guid>https://sin-coder.github.io/post/syn/</guid>
<description>关键词:同步、异步、阻塞、非阻塞 相关概念:网络编程、进程与线程、I/O模型 一、问题背景 同步和异步,以及阻塞和非阻塞都是网络编程中经常遇到的概念,单看文字上的解释确实有些晦涩
难懂。接下来我们将从一个通俗的例子出发阐述它们的区别与联系
二、一个简单的例子 隔壁老王爱好茶艺,每天都会煮开水来泡茶
场景一:老王将水壶放在火上,坐在旁边等待水开 (同步阻塞)
但是这样很耽搁时间,又不自由,效率很低,老王想换种方法
场景二:老王将水壶放在火上,自已去隔壁了,每隔3分钟来看下水开没有 (同步非阻塞)
但是这样依旧很麻烦,老王就买了一个自动报警的水壶
场景三: 老王用新买的水壶进行烧水,坐在旁边等待水开 (异步阻塞)
老王便想没有必要在水壶旁边坐着啊
场景四: 老王新买的水壶放在火上,自己去隔壁了,等着报警再回来 (异步非阻塞)
这种方式是最让老王省心的
小结: 同步和异步关注的焦点在于我们是否需要不断地去看水壶是否开了,同步时,需要老王不断
地去轮询水壶是否开了,效率是比较低下的。而异步时,水壶告警提醒老王它开了
阻塞和非阻塞 关注的焦点在于老王是否需要坐在水壶旁边等待,在水壶旁边等待老王就是阻
塞的,去做其他事的老王就是非阻塞的
这个例子可以帮助我们初步地理解同步异步、阻塞和非阻塞之间的联系和区别,但是如果详细
的“追究”起来,还有许多未解释的细节
三、理论阐述 1.同步与异步 同步和异步(syn &amp; asyn),描述的是在单线程中一次方法调用后,执行者是否具备主动通知
的功能。同步时调用者会等到方法调用返回后才能继续后面的行为,异步时调用者不需要等到方法返回,
方法执行完毕后会主动通知调用者
2.阻塞和非阻塞 阻塞和非阻塞关注是调用者是否可以执行多个任务,描述的是调用者的多个线程是否可以同时执
行。阻塞时,多个线程不能同时进行;非阻塞时,多个线程可以同时进行
3.二者的区别与联系 同步和阻塞完全是在单线程和多线程这两个维度上的概念,它们之间并没有强制的联系。但是从
实际的意义来看确实有一定的绑定关系,比如对于单线程来说,不管是同步还是异步,肯定是阻塞的,非
阻塞只有多线程而且异步的时候才能发挥作用。
回来继续看烧水的例子,老王在烧水的同时去隔壁,也即在烧水这个线程之中,又开启了去隔壁
这个线程,所以使用异步非阻塞才更加有意义</description>
</item>
<item>
<title>虚拟机的网络连接方式</title>
<link>https://sin-coder.github.io/post/virtualnetwork/</link>
<pubDate>Fri, 31 Jan 2020 12:00:31 +0800</pubDate>
<guid>https://sin-coder.github.io/post/virtualnetwork/</guid>
<description> 虚拟机和主机的网络连接方式 最近在使用VirtualBox安装虚拟机组建集群时,总是会遇到各种网络问题,具体包括虚拟机
之间的访问、虚拟机和主机之间的访问、虚拟机访问外网等,搞得晕头转向的,所以在此总结
一下虚拟机和主机之间的网络连接方式,以便更进一步的画出集群的网络拓扑图
在VirtualBox的配置界面,可以看到虚拟机和主机间的网络连接方式有以下几种:网络地址
转换(NAT)、NAT网络、桥接网卡、内部网络、仅主机(Host-only)网络、通用驱动等,下
面便一一详解
1. NAT模式 NAT方式借助网络地址转换的功能,通过宿主机所在的网络来访问互联网。此种方式下,虚拟
机的网卡和物理网卡的网络不是在同一个网络中。虚拟机的网卡只是VirtualBox所提供的一个
虚拟网络,并不真实存在于网络中,所以宿主机无法ping通虚拟机,虚拟机彼此间也不通,但
是通过NAT虚拟机可以访问主机、和主机同网络的其他主机和互联网
不过这里的网络连接方式中有网络地址转换(NAT)和NAT网络,这二者之间又有什么区别呢?
其实这二者本质是相同的,不过后者是提前创建好的网络,在主界面的管理---&gt;全局设定--&gt;网络
我们可以提前设置一个NAT网络供虚拟机来选用
总结起来,NAT模式可以节省网段中的IP地址,适合仅需自己使用的虚拟机配置
2.桥接模式 桥接方式下,虚拟机需要桥接到宿主机的一块网卡上(有线或者无线均可),虚拟机和宿主机
处于同一网段,真实存在于网络中。虚拟机之间可以互通、虚拟机和网络中的主机也可以互通、
只要主机能上网,虚拟机也可上网,但是这样占用网络中的IP地址
3.host-only模式 host-only模式应该是最为复杂的网络连接模式了,其他几种网络的连接方式通过这种模式的合
适配置均可实现。我们可以理解为VirtualBox在主机中模拟出一张专供虚拟机使用的网卡,所
有的虚拟机都是连接到网卡上的,我们可以通过设置这张网卡来实现上网和其他功能。
虚拟机和主机关系,默认不能相互访问,因为不属于同一个IP地址段。但是通过网卡共享、网卡
桥接等,可以实现虚拟机和主机的相互访问
虚拟机和虚拟机的关系,默认同一个网段中的虚拟机是可以相互访问的
4.内部网络 内部网络模式,虚拟机与外网完全断开,虚拟机和主机之间无法相互访问只用于虚拟机
与虚拟机之间的访问,但前提是在虚拟机在同一网络中,实际配置时两台虚拟机设置为
同一网络名称即可,如下图的配置中使用intnet
5.通用驱动 运行用于选择网卡驱动,实际上很少用到,可忽略
6.未指定 相当于虚拟机有网卡,但是没有插线,只能ping自己才会通的
</description>
</item>
<item>
<title>基于Hugo框架搭建个人博客</title>
<link>https://sin-coder.github.io/post/hugo/</link>
<pubDate>Tue, 07 Jan 2020 14:08:20 +0800</pubDate>
<guid>https://sin-coder.github.io/post/hugo/</guid>
<description>关键词:Hugo 、Git、Github、域名解析 概述 1.Hugo简介 Hugo是基于Go语言开发的静态网站生成器,简单、易用、快速部署,主要用于构建个人博客
2.Git简介 Git是目前主流的分布式版本控制工具,有关Git的使用请查看Git的来龙去脉这篇文章
3.Github简介 Github是在外网环境下的一个代码托管库,有关Github的介绍请查看开始玩起Github这篇文章
具体过程 1.准备工作 下载Git并安装、配置环境变量 完成后在终端执行&quot;git&quot;命令来测试是否安装成功,有关git的安装请看Git的来龙去脉
下载Hugo并安装、配置环境变量 完成后在终端执行&quot;hugo version&quot;命令来测试是否安装成功,终端提示如下信息表示安装成功
C:\Users\Administrator&gt;hugo version Hugo Static Site Generator v0.59.1-D5DAB232 windows/amd64 BuildDate: 2019-10-31T15:22:43Z Hugo最好安装在英文目录下
下载时可能由于网络问题失败,附上Hugo、Git、主题m10c的下载包链接: 下载链接
注册Github官网(已有账号请忽略) 2.生成个人站点 (1)在终端执行命令 C:\Users\Administrator&gt;hugo new site E:\hugo\Sites\myblog 出现以下提示信息表示创建成功:
C:\Users\Administrator&gt;hugo new site E:\hugo\Sites\myblog Congratulations! Your new Hugo site is created in E:\hugo\Sites\myblog.</description>
</item>
<item>
<title>高级数据结构(一) 字典树</title>
<link>https://sin-coder.github.io/datastructure/trie/</link>
<pubDate>Fri, 20 Mar 2020 12:41:41 +0800</pubDate>
<guid>https://sin-coder.github.io/datastructure/trie/</guid>
<description> 高级数据结构(一) 字典树 </description>
</item>
<item>
<title>Subseq</title>
<link>https://sin-coder.github.io/leetcode/subseq/</link>
<pubDate>Tue, 10 Mar 2020 19:19:05 +0800</pubDate>
<guid>https://sin-coder.github.io/leetcode/subseq/</guid>
<description></description>
</item>
<item>
<title>Git向Github push时,连接超时</title>
<link>https://sin-coder.github.io/post/git%E8%BF%9E%E6%8E%A5github%E5%A4%B1%E8%B4%A5/</link>
<pubDate>Tue, 28 Jan 2020 17:10:44 +0800</pubDate>
<guid>https://sin-coder.github.io/post/git%E8%BF%9E%E6%8E%A5github%E5%A4%B1%E8%B4%A5/</guid>
<description>Failed to connect to github.com port 443: Timed out 问题背景 最近在使用Git向Github提交时总是会出现以下报错:
E:\hugo\Sites\blog\public&gt;git push -u origin master fatal: unable to access 'https://github.com/sin-coder/sin-coder.github.io.git/': Failed to connect to github.com port 443: Timed out 而且还是偶尔出现的,特别让人心烦,目测为网络问题,折腾了许久在StackOverflow找到了答案
问题原因 为了访问Github更加流畅,本地使用了Shadowsocks进行代理,可是Git并没有走代理访问
只需将Git配置为代理访问Github即可
解决措施 打开Windows下的cmd命令行,在命令行中直接输入以下命令(已经配置Git的环境变量),或者
切换到Git的安装目录下执行命令(未配置环境变量)即可解决该问题
E:\Program Files\Git\Git 的目录 2019/11/27 13:19 &lt;DIR&gt; . 2019/11/27 13:19 &lt;DIR&gt; .. 2019/11/27 13:18 &lt;DIR&gt; bin 2019/11/27 13:19 &lt;DIR&gt; cmd 2019/11/27 13:19 &lt;DIR&gt; dev 2019/11/27 13:19 &lt;DIR&gt; etc 2019/02/26 19:48 149,784 git-bash.</description>
</item>
<item>
<title>Mapreduce</title>
<link>https://sin-coder.github.io/post/mapreduce/</link>
<pubDate>Mon, 27 Jan 2020 00:54:15 +0800</pubDate>
<guid>https://sin-coder.github.io/post/mapreduce/</guid>
<description>1.什么是Map? 什么是Reduce?
Map是拆解 Reduce是组装 本治就是分治法
Input --&gt; Split--&gt;Map---&gt;Shuffle(组装)---&gt;Reduce ----&gt;Finalize(高度并行的)
实现代码:
MapReduce如何实现统计单词出现的次数的
Map(string key, string value) #key : the id of a line #value: the content of the line for each word in value: OutputTemp(word,1) # Reduce 的过程 Reduce(string key,list valueList) #key : the name of a word #valueList: the appearance of this world int sum = 0 for value in valueList: sum+=value OutputFinal(key,sum) MapReduce 如何实现倒排索引的?
MapReduce的整体结构?
总结:Map就是一个disassemble Reduce 就是一个assemble</description>
</item>
<item>
<title>Bigtable</title>
<link>https://sin-coder.github.io/post/bigtable/</link>
<pubDate>Mon, 27 Jan 2020 00:53:53 +0800</pubDate>
<guid>https://sin-coder.github.io/post/bigtable/</guid>
<description>1.如何在文件内进行快速查询?
关键点: 从File 到 Table Table = a list of sorted
2.如何保存一个很大的表?
关键点: A table = a list of tables (小表)
A tablet = a list of sorted
使用MetaData的形式保存每一个小表的位置
3.如何保存一个超大的表?
关键点:A table = a list of tablets (小表)
A tablet = a list of SSTables (小小表)
A SSTables = a list of sorted
4.如何向表中写数据?
关键点:通过写入memTable(内存表)来加速
A tablet = memTable + a list of SSTables
5.内存表过大怎么办?如何避免内存丢失数据?</description>
</item>
<item>
<title>Google File System</title>
<link>https://sin-coder.github.io/post/gfs/</link>
<pubDate>Mon, 27 Jan 2020 00:53:42 +0800</pubDate>
<guid>https://sin-coder.github.io/post/gfs/</guid>
<description>Google File System 一、概述 Google的三篇论文:Google File System 、BigTable 、MapReduce的发表彻底拉开了云计算时代的序幕,同时这三篇论文也是想要入门云计算的学习人员必读的。最近读了这三篇论文,再参考了一些资料后写下自己的总结
HDFS 、HBase 、MapReduce
GFS BigTable MapReducd Google系统整体的架构图如下
GFS系统的优点:高可用性、自动负载均衡
系统的结构:文件系统(GFS)、数据模型(Bigtable)、算法(MapReduce)、应用
在本篇文章中我们着重去描述GFS
二、GFS系统的设计 1.设计思路
(1)组件失效是一种常态,而不是意外;因此持续的监控、错误的侦测、灾难冗余等机制必须集成在GFS
(2)存储的文件非常巨大,基本上为TB级的,I/O操作和Block、Chunk的尺寸都需要规划
(3)对文件的修改以在文件尾部追加数据为主,数据的追加对系统性能有重要的影响
(4)应用程序和文件系统的API协同设计可以大幅度提高系统的灵活性
2.系统的工作负载分析
3.GFS系统架构
三、系统工作原理 设计原则:最小化所有的操作和Master节点的交互
系统具体的工作过程:
3.文件系统的操作
4.Master节点的操作
名称空间管理和锁
副本的位置
创建、重新复制、重新负载均衡、垃圾回收、过期失效的副本检测
5.容错和诊断
高可用性、数据完整性、诊断工具
四、总结 3.Linux文件系统工作原理:
保存一个小文件
保存的每一个文件都有一个元数据Metadata,其中包括filename文件信息 文件名 创建时间 文件大小 index组成文件的每一个Block的索引 关键点为1block = 1024 Byte
保存一个大文件:
关键点为chunk : 1chunk = 64MB =64*1024 =65536 blocks
优点:减少元数据 减少流量 缺点:小文件会浪费较多空间</description>
</item>
<item>
<title>Go语言学习总结(一)</title>
<link>https://sin-coder.github.io/post/go/</link>
<pubDate>Mon, 27 Jan 2020 00:53:21 +0800</pubDate>
<guid>https://sin-coder.github.io/post/go/</guid>
<description>Go语言学习总结(一) 一、Go语言简介 1. Go语言用途 搭载Web服务器,存储集群或类似用途的巨型中央服务器的系统编程语言
在高性能的分布式系统领域,Go语言比其他语言有着更高的开发效率
2. Go语言特点 自动垃圾回收、丰富的内置类型、函数多返回值、错误处理、数组安全
匿名函数和闭包、类型和接口、并发编程、反射、语言交互性等
3. 设计思想 目前主流的编程思想主要有面向对象编程、面向过程编程,但是Go语言在设计的过程中吸收了一些
小众的编程哲学思想,比如函数式编程思想(支持匿名函数与闭包), 面向消息编程思想(支持 goroutine
和通道),因此Go推荐使用消息而不是共享内存来进行并发编程
二、Go语言基础语法 1. 程序组成元素 (1)包声明 源文件中非注释的第一行指明这个文件属于哪个包,如package main, package main表示一个可独立执行的
程序,Go程序是通过package来进行组织的,只有package名称为main的源码文件可以包含main函数
(2)引入包 导入程序所要使用的包 fmt包格式化的输入输出
导入包时可以通过import关键字来单个导入,也可以同时导入多个,如:
//单个导入 import &quot;fmt&quot; import &quot;io&quot; //同时导入多个 import ( &quot;fmt&quot; &quot;math&quot; ) 文件名与包名没有直接关系、同一个文件夹下只能有一个包名,否则编译报错
导入包时一般为 import &quot;项目名/包名&quot;
调用函数时则是通过PackageName.FunctionName() 来进行调用
(3)函数 fun main()是程序开始执行的函数,该函数也是每一个可执行程序所必须的,每个函数后都会有{},但是 &quot; { &quot;</description>