go之八股文總結

kafka爲什麼快

批處理(發送消息時多條緩存起來再發),分片,順序寫,producer2broker(mmap共享空間) broker2consumer(sendFile)。 broker和client之間是有心跳機制的。

kafka過期:用的是時間輪

kafka 消費者組:kafka消費者組默認的分區分配策略,消費者線程數不能大於分區數(當消費者總數大於分區數的話,多餘的消費者進程會一直掛着什麼都不幹,但是當某個消費者線程down掉的話,之前那些多餘的消費者線程會頂替上來),多個消費者組訂閱同一個topic組成廣播。

kafka 零拷貝 directIO mmap sendfile , kafka是leader負責所有的讀寫,followers只是備份。

producer2broker request.required.acks (0:只管發,1:發了要leader確定,-1:發了要同步給所有followers,N/2+1:過半確認返回)

broker2consumer auto.commit.enable (true 消費端自動ack, false 消費端手動ack,手動提交offset),kafka採用的是拉模式消費,消費速度由consumer控制,防止broker推送速度大於consumer消費速度而崩潰。

存儲:kafka以 - 爲存儲文件夾名,裏面的文件按日誌追加形式WAL進行分段 (有很多個小文件,方便舊的整塊刪除)。topic過多順序IO會降爲隨機IO

事務:確保在一個事務中發送的多條消息,要麼都成功,要麼都失敗。注意,這裏面的多條消息不一定要在同一個主題和分區中,可以是發往多個主題和分區的消息(像跟mysql一樣對不同的表update)。當然,你可以在 Kafka 的事務執行過程中,加入本地事務,來實現和 RocketMQ 中事務類似的效果,但是Kafka是沒有事務反查機制的。

kafka之導致Rebalance: partition發生變化;訂閱的Topic個數發生變化(不停的動態訂閱topic);消費者組成員個數發生變化(最常見)。新增成員或已有成員離開。每個消費者都會跟 Coordinator 保持心跳(新版本有獨立的心跳),rebalance時消費者會停止消費,加入到重平衡事件當中。https://www.jianshu.com/p/c2f808af2447

session.timeout.ms 用來控制最大多長時間向coordinator發送自己的心跳不會被認爲超時,默認值10秒。

heartbeat.interval.ms 用來控制發送心跳請求頻率,值越小,發送心跳頻率會越高。

max.poll.interval.ms 限定了消費端應用程序兩次調用poll方法(拉數據)的最大時間間隔,默認值是 5分鐘,業務處理時長大於這個間隔會導致rebalance(消費速度過慢)。

kafka之topic:topic過多順序IO會降爲隨機IO(很多文件一起寫變成隨機io),不停的動態訂閱topic會不停的觸發rebalance。

 

pprof使用流程:

pprof可分析(堆、cpu、協程數、系統線程數、阻塞同步、互斥鎖數) go tool pprof連接進行pprof採集,默認採集30秒。go tool graphviz生成svg文件或火焰圖觀察鏈路和耗時或生成信息放在本地進入pprof終端查看。pprof可分析golang程序cpu佔用過高問題或系統線程數過多cpu負載高。

golang優缺點:編譯型二進制(比php),有GC(比C艹),協程併發,資源利用率高,快速。缺點:過多的err處理對轉語言新人不友好。(框架 包已有)

golang調度: 1、先從本地隊列拿,2、沒有從全局隊列裏拿一半回本地隊列,3、從網絡輪詢器裏獲取並Inject到全局隊列裏,4、從別的P裏偷一半放到本地,注:每61次會從全局隊列裏獲取一個,防止在全局隊列裏的G餓死。

Sysmon監控線程:1.14版後基於信號搶佔

處於_Psyscall狀態的p,當系統調用超過20us時,並隊列裏還有其他G要處理,Sysmon會去搶佔P,把M和G獨立出去運行。

處於_Prunning狀態的p,當運行時間超過10ms時,如死循環,Sysmon會去搶佔G,把當前G調度讓出運行權

2分鐘沒觸發GC,會觸發。生成大量堆內存,GC頻率越來越高,Sysmon會把GC的閾值動態的調高,所以要定期2分鐘清理。

週期性掃描網絡輪詢器,把監聽到數據的goroutine 注入到全局隊列

golang cpu利用率高:死循環或進程有大量計算、GC在執行垃圾回收時,操作系統會不斷對這些有或者沒有被引用的變量進行掃描,這涉及操作系統的算法,執行這種算法時會佔用CPU的資源(sys利用率)。新開闢的變量和內存過多,導致系統不停的檢查是否有不需要引用的變量了,造成佔用CPU資源過多。負載高:還是系統調用導致線程數多,任務數過多。

golang mutex同步原語:其實是把協程gopark放到sudog鏈表裏掛着,解鎖時是goready放進隊列裏。可搜sync_runtime_SemacquireMutex代碼,並不是PV操作(線程級)陷入內核的。讀寫鎖是寫優先於讀的,防讀鎖過多導致寫一直阻塞,讀多寫少RWMutex。寫多讀少mutex就行。

golang內存分配:https://www.cnblogs.com/jiujuan/p/13922551.html https://www.cnblogs.com/jiujuan/p/13869547.html

TCmalloc(ThreadCache(單位object),CentralCache(單位object),PageHeap(單位span))多級內存分配threadCache每個線程都有可以減少鎖開銷,CentralCache空閒塊鏈表數量和threadCache數量相同。

Golang內存管理(mcache(P本地),mcentral(管理全局的mspan),mheap(單位mspan)) 每個P都有獨立的mcache減少鎖開銷,mcentral空閒塊鏈表數量和P數量相同。

申請的內存大於32KB直接申請mheap。

golang defer原理:defer語句在當前G結構體裏的的g._defer鏈表把defer結構體串起來的,新來的defer是推入鏈表頭部的。 關鍵搜索詞:newdefer

函數return執行流程:1.先給返回值賦值(匿名和有名返回值),2.g._defer鏈表的頭開始執行defer結構裏指向的函數,3.包裹函數return返回。

GC STW:混合寫屏障機制,先掃描棧空間對象全部標黑。混合寫屏障 棧空間不啓動,堆空間啓動。

強三色不變性:黑色對象引用的必須是灰色,弱三色不變性:所有被黑色對象引用的白色對象都有被灰色引用或間接引用.

GC流程:

啓動GC時會stop the world啓動混合寫屏障,掃到所有棧上堆上的root的對象加入隊列,然後start the word。然後併發掃描各個goroutine的棧,使其變黑並一直保持,這個過程不需要STW. 完成GC後會stop the world關閉混合寫屏障

1.雖然 golang 是先實現的插入寫屏障,後實現的混合寫屏障,但是從理解上,應該是先理解刪除寫屏障,後理解混合寫屏障會更容易理解;

2.插入寫屏障沒有完全保證完整的強三色不變式(棧對象的影響),所以賦值器是灰色賦值器,最後必須 STW 重新掃描棧;

3.混合寫屏障消除了GC期間的所有的 STW,實現的是黑色賦值器,不用 STW 掃描棧;

混合寫屏障的精度和刪除寫屏障的一致,比以前插入寫屏障要低;

4.混合寫屏障掃描棧式逐個暫停,逐個掃描的,對於單個 goroutine 來說,棧要麼全灰,要麼全黑;

5.暫停機制通過複用 goroutine 搶佔調度機制來實現;

6.生成大量堆內存,GC頻率越來越高,Sysmon會把GC的閾值動態的調高,以減少GC次數,所以會有固定2分鐘清理一次。也別寫內存泄漏代碼。

內存逃逸(逃逸分析):外部引用(指針逃逸)、動態變量大小逃逸(for循環 length是變量)、動態類型逃逸(不確定大小)、棧空間不足逃逸(對象太大)、閉包引用對象逃逸

make與new的區別,new返回結構體指針,make用到特殊類型channel、map、slice。返回對應結構體

P的最大上限 256:

 

高併發系統:核心思想,緩存、多級緩存、分片、集羣、主從、異步削峯、限流過載保護、壓測、服務化+熔斷

webscoket常用:推事件 拉數據

websocket協議規範:https://learnku.com/docs/eudore/14-http-websocket/9653 特別注意頭信息 textMessage BinaryMessage PingMessage PongMessage

前端平滑新按鈕更新添加 推事件廣播,前端再拉數據,推拉結合

websocket推更新事件,前端監聽到後請最新的js css代碼動態覆蓋更新

 

 

Nginx驚羣:有用進程鎖去處理

HTTPS: 爲什麼要rsa和aes結合,對稱加密(aes)具有加解密速度快,性能高的特點 ,而rsa保密性好,性能不佳。所以是先rsa加密aes互相得到對稱密文,然後aes進行加密通信。當keepalive到時,重新發起https裏aes密文會變

HTTPS流程:1:個人信息和公鑰hash成摘要、2:然後用私鑰加密成數據簽名,數據簽名和公鑰個人信息hash算法一起發出去、3:然後用公鑰解數據簽名得到摘要,和發過來的信息生成的摘要進行對比、4:最後得到互相通信的加密算法

HTTP2.0:二進制分幀(獨立的stream幀) 首部壓縮(兩端維護了header索引表,以後傳輸用下標) 多路複用(虛擬信道,獨立的幀時分複用發送) 請求優先級 服務器推送(雙向流)

web安全:

xss :過濾帶html標籤的字符串

csrf :攻擊者盜用了你的身份,以你的名義發送惡意請求。

防範:同源檢測(origin referer)、帶token提交驗證、雙重Cookie驗證(url上帶字段與cookie裏的字段校驗) ,設置cookie裏的Samesite屬性用來標明這個Cookie是個“同站 Cookie”

sql注入 預編譯語句和參數化查詢

 

 

etcd異地多活 鏡像模式mirror-maker、raft協議 (數據同步,選主)。是CP系統,當發生網絡分區時,有個區會重新選主,但少的區無法複製到大多數,成爲不可用,另一個區是大多數可正常進行同步保證一致,對外部而言是保證一致的。

微服務框架、GRPC與HTTP2.0

網關限流,服務限流。

而熔斷降級作爲保護服務自身的手段,通常是在客戶端進行規則配置和熔斷識別:

 

 

CPU:

孤兒進程:一個父進程退出,而它的一個或多個子進程還在運行,那麼那些子進程將成爲孤兒進程。孤兒進程將被init進程(進程號爲1)所收養,並由init進程對它們完成狀態收集工作。

殭屍進程:一般工作中叫Z進程,即一個進程使用fork創建子進程,如果子進程退出,而父進程並沒有調用wait或waitpid獲取子進程的狀態信息,那麼子進程的進程描述符仍然保存在系統中。這種進程稱之爲殭屍進程,如何處理Z進程 ,殺死父進程,都轉成孤兒進程讓init進程處理。cpu負載過高說明任務過多,或是殭屍進程過多

CPU的利用率:CPU處於用戶態執行的時間(users),系統內核執行的時間(sys),和空閒系統進程執行的時間(idle)。平時說的CPU利用率是指:1-CPU空閒運行時間/總運行時間. CPU利用率顯示的是程序在運行期間實時佔用的CPU百分比 https://blog.csdn.net/longerzone/article/details/8631183

CPU負載計算:取決於CPU任務隊列長度而不是CPU利用率,使用CPU隊列長度則可以很直接反應CPU的負載量。load average 是對 CPU 負載的評估,其值越高,說明其任務隊列越長,處於等待執行的任務越多。就是一段時間內一共有多少任務在使用或等待使用CPU。CPU負載顯示的是一段時間內正在使用和等待使用CPU的平均任務數。CPU利用率高,並不意味着負載就一定大。

CPU負載分擔到每個CPU上的負載是多少呢?那就要看我這臺服務器有一共有多少個內核了。比如:4個內核15分鐘的負載最理想的狀態是4*0.7

https://blog.51cto.com/zhanglm/1952818

https://blog.csdn.net/zouli415/article/details/79794355

CPU時間 = user(用戶態)+sys(內核態)+nice()+idle(IO等待以外其它等待時間)+iowait(硬盤IO等待時間)+irq(硬中斷時間)+softirq(軟中斷時間)

操作系統:

mmap與brk:brk申請的內存是連續的,mmap則不需要

內核態:cpu可以訪問內存的所有數據,包括外圍設備,例如硬盤,網卡,cpu也可以將自己從一個程序切換到另一個程序。系統調用用戶態會陷入內核態。

用戶態:只能受限的訪問內存,且不允許訪問外圍設備,佔用cpu的能力被剝奪,cpu資源可以被其他程序獲取。當系統調用時用戶態的cpu上下文是保存在內核棧的pt_regs裏。

用戶態和內核態:在CPU的所有指令中,有些指令是非常危險的,如果錯用,將導致系統崩潰,比如清內存、設置時鐘等。防止他們獲取別的程序的內存數據、獲取外圍設備的數據, 併發送到網絡。如果所有的進程都能使用這些指令,那麼系統死機的概率將大大增加。所以要設置級別權限。(系統調用 ,缺頁異常,外設中斷會用戶態陷入內核態)

文件操作:

1、在寫文件的時候同時刪除文件,文件依舊可以讀寫,多進程打開文件時inode裏的i_count會增加,在刪除文件時i_count爲0時才真正刪除(類似引用計數,標記有多少個進程打開) i_nlink是硬連接計算 https://www.cnblogs.com/yangyuliufeng/p/9339088.html

2、同一個文件是可以open多次的。每次open都會建立一個新的file句柄/指針與file結構體,指向同一個文件的inode節點。生成子進程時會共享file結構體。

線程同步和進程同步的本質區別在於鎖放在哪,放在私有的進程空間還是放在多進程共享的空間,並且看鎖是否具備進程共享的屬性

多線程同步:互斥鎖、自旋鎖、讀寫鎖、條件變量。在linux裏線程和進程是同一結構體task_struct,多線程的本質仍是進程。

多進程同步:設置信號量+對信號量做PV原語操作(信號與信號量區別),消息隊列、管程、文件大鎖。多線程的本質仍是進程

死鎖 :兩進程/線程,兩資源上鎖,產生了鎖交叉,

進程通信:套接字、消息隊列、共享內存空間、管道、遠程過程調用、信號(父子進程wait/waitpid)。linux裏線程和進程是同一結構體task_struct

進程/線程調度:FIFO、短進程優先、最高響應比優先、時間片輪轉法、最短剩餘時間優先、多級反饋隊列算法。調度時Cpu上下文件會存到進/線程的thread_struct裏,thread_info用於系統快速找到task_struct

虛擬內存:變量操作->訪問快表->訪問虛擬內存地址->訪問頁目錄(是否有對應物理內存)->產生缺頁異常中斷->判斷有沒有足夠的物理內存(沒有就髒頁刷盤)->訪問磁盤swap空間->加載到內存->設置頁表。夥伴系統。內存對齊:代碼裏小類型數據聚一起可以內存對齊,好處內存碎片大大減少,節省空間。

虛擬內存尋址空間:

尋址空間,用戶態所佔空間和內核態所佔空間大小几乎各一半(32位)

零拷貝:directIO mmap(connfd->filefd 4 次上下文切換,1 次 CPU 拷貝和 2 次 DMA 拷貝) sendfile(filefd->connfd 2次上下文切換,1 次 CPU 拷貝)

mmap的優缺點:

優點:

1、省了傳統讀寫的用戶態和內核態的cpu上下文切換,提高了大文件讀寫效率。

缺點:

1、mmap是按頁做映射的所發如果文件小於4KB也是佔用4KB內存,如果連續mmap小文件會浪費很多內存空間

2、mmap映射文件的大小是不能超過文件大小,所以要提前得之文件大小,不能動態擴展文件。

3、如果系統頻繁的使用mmap操作,而且每次mmap的size都不同,那麼就會使得內存可能缺少足夠的連續的內存空間。

進程切換:

1.切換頁目錄以使用新的地址空間並要刷掉快表。

2.切換內核棧和硬件上下文。

線程切換:

1.只切換內核棧和硬件上下文,切換時要陷入內核。

協程切換:協程(2kb內存)切換沒有內核的開銷協程上下文切換隻涉及到cpu三個寄存器(PC程序計數器 / SP堆棧指針 / DX寄存器)的值修改(協程切換隻涉及基本的CPU上下文切換,而且是由P執行處理無內核幫忙,切換隻發生在用戶態);而對比線程的上下文切換則需要涉及模式切換(線程切換,cpu要用戶態陷入內核態,要操作系統去完成線程調度,還有線程私有棧(內核棧)的切換 要切換的上下文比協程多,再返回用戶態)

協程切換的時機:1、select阻塞時,2、io(文件,網絡)讀寫阻塞時,3、channel阻塞時,4、等待鎖,5、sleep時,6、runtime.Gosched()這些阻塞時會調用gopark把協程切換出去到對應的結構體裏掛起,當就緒goready時會把他們扔回全局隊列等待調度。系統調用時間過長時會切出去獨立 線程處理。

https://blog.csdn.net/m0_37145844/article/details/106412949

網絡:

http狀態碼:504(nginx網關執行/等待超時)、502(Nginx發現與自己通信的連接斷掉/找不到了,常駐進程裏常見程序panic退出或是進程未啓動)

TCP通信:當服務器返回數據修改TCP包服務器源IP時,對端是否可以收到 。可以,操作系統並不檢測對端源ip地址信息。但是會對checkSum做校驗處理,在校驗和生成之前修改源IP,再發送給對端,對端是可以接收包的,並不檢驗源ip地址。

TCP爲啥可靠:ACK和超時重發機制、滑動窗口流控、擁塞控制(慢啓動,快重傳,快恢復)

TCP校驗和:做校驗處理,TCP校驗和也包括了96位的僞頭部,其中有源地址、目的地址、協議以及TCP的長度。這可以避免報文被錯誤地路由。

路由轉發:由A發給路由器B,B經過重封裝後,源IP和目標IP是不變的,源MAC地址變成B2的MAC地址目標MAC地址變成C1的MAC地址

timewait作用

1:保證服務端ack沒收到重發

2:舊連接持續時間內所產生的所有報文都從網絡中消失,如果沒有timeWait 新的連接可能會同ip同端口,傳播延遲的數據包會被新連接 接收 。有timewait了2msl的時間足夠消化延遲數據包或讓其消散。

通用連接池:https://studygolang.com/articles/12333

timewait過多導致的問題,closewait過多導致的問題

服務端重啓,tcp連接異常關閉問題:在發ping時對端會發RST重,會報connection reset by peer https://zhuanlan.zhihu.com/p/390939380

URG(緊急包) SYN(握手) FIN(揮手) PSH(推數據) RST(重置過期連接) ACK(確認) TCP六標誌位

TCP中的半鏈接與全鏈接

epoll: 是沒有用mmap的,默認是水平觸發。

epoll_ctl把connfd放到epollfd並拷貝到內核態,有數據來時對應connfd複製到rdlist

epollwait系統調用 會判斷rdlist是否爲空,不爲空則把fd信息從內核態複製到用戶態數組裏。

水平觸發:沒有把數據一次性全部讀寫完,那麼下次調用 epoll_wait()時,它還會通知你在上沒讀寫完的文件描述符上繼續讀寫,當然如果你一直不去讀寫,它會一直通知你

邊緣觸發:沒有把數據全部讀寫完,那麼下次調用epoll_wait()時,它不會通知你,也就是它只會通知你一次,直到該文件描述符上出現第二次可讀寫事件纔會通知你!!!

 

mysql:索引表 回表 覆蓋索引 sql語句 全同步 半同步(等待至少一個從庫接收到並寫到relay log中才返回給客戶端)複製

三範式:1NF:字段不可分,每個字段是原子級別的、2NF:有主鍵,非主鍵字段依賴主鍵,ID字段就是主鍵,它能表示這一條數據是唯一的、3NF:非主鍵字段不能相互依賴

mysql主從複製:主庫寫入binlog、salve開啓一個I/O Thread,該線程在master打開一個連接,主要工作是拉取binlog的最新數據寫入relay log裏,寫入relayLog裏成功就可以返回響應給主庫了、SqlThread會讀取中繼日誌的最新內容,並順序執行該日誌中的SQL事件(連接上主庫,主庫會把binlog發送給從庫)

mysql分庫分表:一致性Hash(解決數據二次全量遷移散列的問題,一致性hash隻影響遷移的相鄰節點,注意熱點節點要進行虛擬節點多節點擴散)

mysql刪除記錄:是打個delete標記,並沒有真正刪,是由後臺線程purse在定時處理,刪記錄表空間不縮小(防頁移動產生的隨機io),清碎片得手動重建表並遷移。

mysql在線數據遷移:

mysql鎖:行鎖、表鎖、間隙鎖、next-key lock、自增鎖、意向共享鎖(讀)、意向排他鎖(寫),當加行鎖時也會給表上一個意向鎖(意向鎖間不阻塞),意向鎖的作用是當加表鎖時無需去遍歷整張表判斷哪個記錄有沒有上鎖,直接被意向表鎖阻塞。

沒有索引的列,當前讀操作時,會加全表gap鎖,生產環境要注意。

非唯一索引列,如果where條件部分命中(>、<、like等)或者全未命中,則會加附近Gap間隙鎖。例如,某表數據如下,非唯一索引2,6,9,9,11,15。如下語句要操作非唯一索引列9的數據,gap鎖將會鎖定的列是(6,11],左開右閉,該區間內無法插入數據。

當一條sql的where上的條件沒有索引的話會直接使用表鎖,而不是行鎖

自增鎖: 表級鎖,在insert完後就釋放鎖了,並不會伴隨整個事務

 

mysql事務執行流程:開啓事務、索引表記錄加行鎖、讀數據到cache上、修改前的數據寫undolog(持久化)、修改數據cache的的值、修改後的數據寫redolog buffer、寫binlog cache(滿了寫到binlog臨時文件)、commit觸發2pc(redologbuffer持久化到redologFile prepare狀態 持久化binlogCache到binlogFile(釋放臨時資源binlog Cache redologFile commit狀態)) 。

binlog 格式:Statement 格式存的是執行語句容易主從不一致,較少用、row格式會存兩條數據,更新前和更新後的值 佔空間,較常用,能保證主從一致。

redolog記的是對物理數據頁的修改、順序寫。

當前讀:讀取的是最新版本,並且對讀取的記錄加鎖,阻塞其他事務同時改動相同記錄 select in share mode, select for update, update, delete, insert

快照讀:單純的select操作開啓事務後第一個select語句纔是快照讀的地方,undolog和多版本併發控制MVCC實現

幻讀:幻讀是針對當前讀的,在RR下真正解決幻讀是Next-Key 鎖,當前讀下會用Next-key鎖 鎖住記錄和條件的左右間隙,當有insert操作時會間隙鎖阻塞。不能insert新數據,再在當前讀時就不會出現幻讀。

MVCC:MVCC是針對快照讀的,RR級別開事務時只生成一次視圖,RC每次select時都重新生成視圖,活躍事務數組配合undolog讀取比自己事務ID小或等於自己事務ID的快照記錄。

https://blog.csdn.net/qq_31930499/article/details/110393988 快照圖與當前讀

 

mysql高可用:

MHA(MHA能做到在0~30秒之內自動完成數據庫的故障切換操作,並且在進行故障切換的過程中,MHA能在最大程度上保證數據的一致性,以達到真正意義上的高可用,1、主要是基於半同步複製有一個slave裏有最新的數據。2、當binlog來不及傳送時會嘗試登陸主庫傳送binlog,當binlog傳送的時間過長 全中斷半同步複製轉爲異步複製,這時磁盤上會遺留很多未複製的binlog,會導致從庫拉起成主庫後數據丟了。這個是用在服務沒掛的情況)

MHA:MySQL 服務掛了,但是可以從服務器拷貝二進制。但如果硬件宕機或者 SSH 不能連接,不能獲取到最新的 binlog 日誌,如果複製出現延遲,會丟失數據。使用 MySQL5.5 的半同步複製,可以大大降低數據丟失的風險。MHA 可以和半同步複製結合起來。如果只有一個 Slave 已經收到了最新的二進制日誌,MHA 可以將最新的二進制日誌應用於其他所有 Slave 服務器上,保持數據一致性。最新版 0.56 版本,增加了支持 GTID 的功能,建議在 MySQL5.6 及之後版本使用。MySQL5.5建議使用管理節點版本 0.55,數據節點 0.54。

(所謂主從複製拖後半同步轉爲異步原理)另外,在半同步複製時,如果主庫的一個事務提交成功了,在推送到從庫的過程當中,從庫宕機了或網絡故障,導致從庫並沒有接收到這個事務的Binlog,此時主庫會等待一段時間(這個時間由rpl_semi_sync_master_timeout的毫秒數決定),如果這個時間過後還無法推送到從庫,(主從同步延時過長)那MySQL會自動從半同步複製切換爲異步複製,當從庫恢復正常連接到主庫後,主庫又會自動切換回半同步複製。

MMM (由於MMM無法完全的保證數據一致性,{因爲備主掛了後,活主把數據同步給從庫後,啓動備主,不巧活主掛了,此時備主數據落後於從庫},所以MMM適用於對數據的一致性要求不是很高,但是又想最大程度的保證業務可用性的場景)

b+樹擴縮容方式:https://www.jianshu.com/p/71700a464e97

每個中間節點都至少包含ceil(m/2)個孩子,最多有m個孩子。無論插入多少元素要始終保持最大元素在根節點當中。

1)若爲空樹,創建一個葉子結點,然後將記錄插入其中,此時這個葉子結點也是根結點,插入操作結束。

2)針對葉子類型結點:根據key值找到葉子結點,向這個葉子結點插入記錄。插入後,若當前結點key的個數小於等於m-1,則插入結束。否則將這個葉子結點分裂成左右兩個葉子結點,左葉子結點包含前m/2個記錄,右結點包含剩下的記錄,將第m/2+1個記錄的key進位到父結點中(父結點一定是索引類型結點),進位到父結點的key左孩子指針向左結點,右孩子指針向右結點。將當前結點的指針指向父結點,然後執行第3步。

3)針對索引類型結點:若當前結點key的個數小於等於m-1,則插入結束。否則,將這個索引類型結點分裂成兩個索引結點,左索引結點包含前(m-1)/2個key,右結點包含m-(m-1)/2個key,將第m/2個key進位到父結點中,進位到父結點的key左孩子指向左結點, 進位到父結點的key右孩子指向右結點。將當前結點的指針指向父結點,然後重複第3步。

 

B+樹:

m階B+樹表示了內部結點最多有m-1個關鍵字(或者說內部結點最多有m個子樹),階數m同時限制了葉子結點最多存儲m-1個記錄。

所有關鍵字存儲在葉子節點出現,內部節點(非葉子節點並不存儲真正的 data) 。爲所有葉子結點增加了一個鏈指針

B+樹葉節點兩兩相連可大大增加區間訪問性,可使用在範圍查詢等,而B-樹每個節點 key 和 data在一起,則無法區間查找。

假設主鍵爲bigint類型,InnoDB 的bigint佔用8個字節,指針佔用6個字節,8+6=14,所以我們可以得出,一個page能存放的指針個數爲16k/(8+6)約等於1170

B樹 :

所有鍵值分佈在整顆樹中(索引值和具體data都在每個節點裏);

任何一個關鍵字出現且只出現在一個結點中;

搜索有可能在非葉子結點結束(最好情況O(1)就能找到數據);

在關鍵字全集內做一次查找,性能逼近二分查找;

 

B樹和
B+樹的最大區別 在於範圍查詢時的過程與性能B+樹適用於範圍查找:B樹要中序遍歷不斷的進行“回溯”過程,會帶來較多的隨機
IO,B+樹鏈表一直Next就行了能順序IO。

B+樹用鏈表往下找就行了

 

redis-mysql 一致性 (延遲雙刪)

分佈式鎖 跳錶 腦裂

 

Redis事務操作:(mutli exec最好就同一key)、lua原子操作

string:有點像golang的slice 動態字符串(字符數組[]buf,len長度,free 數組buf剩餘空間)

list:雙向鏈表

set:長度小於512用inset(可以理解爲數組),長度大於512用 hashtable

zset組成:(字典(dict)+多級鏈表(zskiplist),dict用於member找score(zscore指令), 多級鏈表用於score範圍查找)https://zhuanlan.zhihu.com/p/193141635

ziplist編碼:是一個經過特殊編碼的雙向鏈表,它的設計目標就是爲了提高存儲效率。當zset保存的元素數量小於128個,所有元素的長度小於64字節 用ziplist

redis驚羣 redsi緩存消失 高併發下所有請求打到數據庫,用分佈式鎖防等redis緩存有數據

redis主從同步操作:redis主從同步是異步同步的,當主庫掛了,哨兵會找一個最優的從庫當主庫( 1:從庫優先級、2:從庫複製進度、3:從庫 ID 號,一般優先都一樣、所以是先找複製進度最快的從庫拉起當主庫,減少數據不一致的損失)

redis接入新從庫時,先rdb全量同步,寫操作放緩衝區增量同步(replBacklogBuffer環形數組,Slave在同步掉線時不用再全局同步,可以在原來的位置繼續同步),

redis持久化:RDB(阻塞只發生在fork子進程階段) 、AOF(時時fsync、只寫頁緩存(write)、時時write但每秒fsync)、4.0後新增混合持久化(aof rewrite 的時候就fork子進程做rdb持久化把 rdb的內容寫到 aof 文件開頭,以前的aofrewrite要aof重寫緩衝區做增量追加)https://baijiahao.baidu.com/s?id=1654694618189745916&wfr=spider&for=pc

開啓混合存儲模式後 aof 文件加載的流程如下:

aof 文件開頭是 rdb 的格式, 先加載 rdb 內容再加載剩餘的 aof

aof 文件開頭不是 rdb 的格式,直接以 aof 格式加載整個文件

 

redis哨兵模式: 高可用流程,單哨兵監測到並轉爲主觀下線,通知其他哨兵,N/2+1哨兵主觀下線轉客觀下線 ,主庫下線,哨兵們發起投票raft由誰成爲leader進行選主(1:從庫優先級、2:從庫複製進度、3:從庫 ID 號,一般優先級一樣,找複製進度最快的減少數據不一致)

redis-cluster模式 : 高可用流程,某個節點主觀下線 通知其他節點,過半主觀下線則客觀下線。然後各個主節點去故障的從節點進行選舉投票找出最合適的從節點替換成主節點(和哨兵一樣,也是選複製進度快的)。

redis分佈式限流:全局性和本地性 像golang的groutine的全局隊列和P的本地隊列。https://pandaychen.github.io/2020/06/01/REDIS-DISTRIBUTED-LOCK/

redis分佈式限流之發票服務器:這種方案的思想是建立在Redis令牌桶方案的基礎之上的。如何解決每次取令牌都伴隨一次網絡開銷,該方案的解決方法是建立一層控制端,利用該控制端與Redis令牌桶進行交互,只有當客戶端的剩餘令牌數不足時,客戶端才向該控制層取令牌並且每次取一批。

redis的過期策略: 會將每個設置了過期時間的 key 放入到一個獨立的字典中,以後會定時遍歷這個字典來刪除到期的 key。除了定時遍歷之外,它還會使用惰性策略來刪除過期的 key,所謂惰性策略就是在客戶端訪問這個 key 的時候,redis 對 key 的過期時間進行檢查,如果過期了就立即刪除。定時刪除是集中處理,惰性刪除是零散處理。

分佈式鎖:刪除鎖時的唯一值判斷,防鎖被其他線程刪除

緩存雪崩:大面積緩存同時過期

緩存擊穿:緩存突然消失 全打到數據庫

緩存穿透:數據庫沒有這條記錄,緩存裏沒有,數據庫裏也沒有,所有訪問直穿數據庫,一直在刷。設置空值一段時間,或用布隆過濾器:bitmap。

redis漸進式rehash :新開一個2倍的哈希表,將rehashindex的值設置爲0,在rehash期間,每次對字典執行增刪改查,還會順帶將ht1哈希表在rehashindex(桶)上的所有鍵值對rehash到ht2,當rehash工作完成以後,rehashindex的值+1,隨着字典操作的不斷執行,ht0的所有鍵值對都會被rehash到ht2,將rehashindex的值設置爲-1,表示rehash操作結束。 漸進式rehash採用的是一種分而治之的方式,將rehash的操作分攤在每一個的訪問中,避免集中式rehash而帶來的龐大計算量。

 

CAP理論

分佈式Id:雪花算法 64位 第1位不用,41位毫秒級時間戳,10位工作機器ID(可自定義同步到etcd裏),12位步長。趨勢遞增:99.999%情況是順序寫IO,0.001%的情況是隨機寫IO

mysql全同步複製 cp系統 ,mysql半同步複製 ap系統

 

cap理論的應用:強一致性強調的是強一致性讀,寫響應返回後其他請求立馬去讀能讀到最新值

 

 

分佈式事務可以ap(最終一致),也可以cp(強一致 加鎖同步完成才參訪問) ,ca(沒有分佈式,單點)

ap : 放棄強一致,追求分區容錯性和可用性,mysql redis kafka 主從同步,異步同步 最終一致 。

cp : 數據庫主從同步,全同步,從庫加鎖鎖定,同步完成了從庫才能訪問,同步的過程從庫不能對外提供服務。在網絡分區的情況下強調強一致性讀。所有設計是爲了一致性,當發生網絡分區時,爲了保證一致性,是不可用的。如:etcd ,zk

etcd 分佈式強一致算法,過半follower同步完成才返回,​ 放棄可用性,追求一致性和分區容錯性,我們的zookeeper其實就是追求的強一致,又比如跨行轉賬,一次轉賬請求要等待雙方銀行系統都完成整個事務纔算完成,如果後面的某個節點掛了,必然返回失敗,只要轉賬成功,立馬去讀一定讀到最新的值。

ca :無多機器網絡隔離 單機

 

 

 

 

 

linux指令:

awk 是逐行處理文本(awk處理超大文件,大文件模糊查詢正則匹配),不會佔據大量內存,而且 awk 執行效率也挺高,可以用來處理超大型文件。

listof 顯示進程已打開文件數

natstat 網絡狀態相關查詢

 

高級數據結構:

基數樹(radix 壓縮前綴樹): https://learnku.com/docs/eudore/example-radixtree/10178

 

動態負載均衡原理

後端服務動態更新計算得出後的權值

動態更新加權輪詢的權值

然後按加權輪詢去負載均衡

重試有好幾種情況

1. fastfail

2. sleep重試 解決閃斷

3. 批量掃描重試,解決最終一致性, 支付常見

4. mq排隊+ack重試,解決丟失,以及同一個對象需要時序問題

5.面試問題:買家和賣家分表各自要查詢,把公共部分獨立出來垂直分表維護一份

 

TCP的滑動窗口與大文件散片上傳的優缺點

監控系統 : 分治思想 各區域子數據中心收集服務器信息(服務器上報,每秒一次) 總中心:區域中心再把收集到的數據一同發給總中心(每5秒一次)

 

下表總結了若干Linux下的工具:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章