知識集錦

BigC哥發表於2020-11-20

Kafka專題:1.kafka高效能的原因

高效能包含兩個方向
寫的高效能
1)順序寫+page cache
2)生產者批量傳送訊息集,壓縮:生產者並不直接將訊息傳送給服務端,先在客戶端把訊息放入佇列中,然後由一個訊息傳送執行緒從佇列中拉取訊息,以批量的方式傳送給服務端。同一個節點上面的不同分割槽訊息會一個批次傳送,減少網路傳送次數。kafka使用selector處理網路連線與讀寫處理。
讀的高效能
1)順序讀+Zero copy
2)消費者批量拉取(可以指定大小)

開發者提升效能的手段
1)增加partition+增加消費者例項

什麼時候為提交成功呢?
所有的ISR節點都寫入成功,才算提交成功(注意,isr節點不是所有副本節點,是所有節點的一個子集,在PartitionInfo類中,包含兩個屬性 Node[] replicas 分割槽所有副本;另一個是Node[] inSyncReplicas 也就是ISR節點列表,當一個副本落後主副本太多,就會從isr列表中移除,避免影響訊息的commit)

有序性如何保證?
同一分割槽內訊息有序,不同的分割槽,訊息無序。(對需要保證消費順序的訊息放到同一分割槽即可)

訊息是如何負載均衡到某一個分割槽的呢?
1)round robin 隨機輪詢(訊息沒有key)
2)對key進行雜湊化,對分割槽數量取模得到分割槽編號
3)訊息在生產者客戶端就已經確定好了partition的id,每一個partition有一個雙端佇列來快取客戶端的訊息,佇列滿了才進行一次向伺服器的傳送。傳送的時候,是以節點為單位的,比如一個節點上有10個分割槽,這10個分割槽的訊息,是一次網路請求進行傳送的。

客戶端網路連線物件NetworkClient管理了客戶端與服務端之間的網路通訊,包括連線的建立,傳送客戶端請求,讀取客戶端響應。
包含三個方法
1)ready (),服務端是否準備好,如果準備好,呼叫Selector.connect()方法建立連線
2)send(),將客戶端請求加入inFlightRequests列表,然後呼叫Selector.send()方法,這一步只是將請求暫存到節點對應的網路通道中,還沒有真正的傳送出去。
針對同一個服務端,如果上一個客戶端請求還沒有傳送完成,則不允許傳送新的客戶端請求。InFlightRequests類包含一個節 點到雙端佇列的對映結構。 在準備傳送客戶端請求時,請求將新增到指定節點對應的佇列中;在收到 響應後 ,才會將請求從佇列中移 除 。
3)poll(),真正的傳送,呼叫Selector.poll方法

常見的題

N階樓梯問題(動態規劃)

https://blog.csdn.net/xiao_chen_l/article/details/81174900

查詢陣列中第k大的數

問題: 查詢出一給定陣列中第k大的數。例如[3,2,7,1,8,9,6,5,4],第1大的數是9,第2大的數是8……

思考:1. 直接從大到小排序,排好序後,第k大的數就是arr[k-1]。
https://www.cnblogs.com/wsw-seu/p/7652495.html

go快排

1.選取基準值tag:選取第一個元素為基準值(每次遞迴呼叫的基準值不等)
2.從0向後查詢到比tag大的數,否則i++
3.從n向前查詢到比tag小的數,否則j–
4.交換兩個數
5.全部交換後此時i==j,遞迴呼叫,繼續比較i位置兩側位置

//第一種方式,遞迴傳入分割後的陣列
func quicksort(s []int){
    if len(s)<=0 {
        return
    }
    tag:=s[0]
    i:=0
    j:=len(s)-1
    for i<j  {
        for s[j]>tag&&i<j {
            j--
        }
        for s[i]<tag&&i<j {
            i++
        }
        s[i],s[j]=s[j],s[i]//交換
    }
    quicksort(s[:i])
    quicksort(s[i+1:])
}
//第二種方式,遞迴傳入原陣列
func quicksort(s []int,start int,end int){
    if start >=end{
        return
    }
    tag:=s[start]
    i:=start
    j:=end
    for i<j  {
        for s[j]>tag&&i<j {
            j--
        }
        for s[i]<tag&&i<j {
            i++
        }
        s[i],s[j]=s[j],s[i]//交換
    }
    quicksort(s,start,i-1)
    quicksort(s,i+1,end)
}

資料結構

二叉樹的銷燬

https://www.cnblogs.com/Romi/archive/2012/08/30/2664575.html
####如何判斷單連結串列是否有環,如果有怎麼找到進入環的節點
https://blog.csdn.net/weixin_30840573/article/details/95642135

Go語言——垃圾回收GC

Go語言——垃圾回收GC
參考:

Go 垃圾回收原理

Golang原始碼探索(三) GC的實現原理

Getting to Go: The Journey of Go’s Garbage Collector

Go的三色標記GC

引用計數:對每個物件維護一個引用計數,當引用該物件的物件被銷燬時,引用計數減1,當引用計數器為0是回收該物件。
優點:物件可以很快的被回收,不會出現記憶體耗盡或達到某個閥值時才回收。
缺點:不能很好的處理迴圈引用,而且實時維護引用計數,有也一定的代價。
代表語言:Python、PHP、Swift
標記-清除:從根變數開始遍歷所有引用的物件,引用的物件標記為"被引用",沒有被標記的進行回收。
優點:解決了引用計數的缺點。
缺點:需要STW,即要暫時停掉程式執行。
代表語言:Golang(其採用三色標記法)
分代收集:按照物件生命週期長短劃分不同的代空間,生命週期長的放入老年代,而短的放入新生代,不同代有不能的回收演算法和回收頻率。
優點:回收效能好
缺點:演算法複雜
代表語言: JAVA
root
首先標記root根物件,根物件的子物件也是存活的。

根物件包括:全域性變數,各個G stack上的變數等。

標記
在之前的Go語言——記憶體管理一文中,分析過span是記憶體管理的最小單位,所以猜測gc的粒度也是span。

type mspan struct {
    // allocBits and gcmarkBits hold pointers to a span's mark and
    // allocation bits. The pointers are 8 byte aligned.
    // There are three arenas where this data is held.
    // free: Dirty arenas that are no longer accessed
    //       and can be reused.
    // next: Holds information to be used in the next GC cycle.
    // current: Information being used during this GC cycle.
    // previous: Information being used during the last GC cycle.
    // A new GC cycle starts with the call to finishsweep_m.
    // finishsweep_m moves the previous arena to the free arena,
    // the current arena to the previous arena, and
    // the next arena to the current arena.
    // The next arena is populated as the spans request
    // memory to hold gcmarkBits for the next GC cycle as well
    // as allocBits for newly allocated spans.
    //
    // The pointer arithmetic is done "by hand" instead of using
    // arrays to avoid bounds checks along critical performance
    // paths.
    // The sweep will free the old allocBits and set allocBits to the
    // gcmarkBits. The gcmarkBits are replaced with a fresh zeroed
    // out memory.
    allocBits  *gcBits
    gcmarkBits *gcBits
}

bitmap

如圖所示,通過gcmarkBits點陣圖標記span的塊是否被引用。對應記憶體分配中的bitmap區。

三色標記
灰色:物件已被標記,但這個物件包含的子物件未標記
黑色:物件已被標記,且這個物件包含的子物件也已標記,gcmarkBits對應的位為1(該物件不會在本次GC中被清理)
白色:物件未被標記,gcmarkBits對應的位為0(該物件將會在本次GC中被清理)
例如,當前記憶體中有A~F一共6個物件,根物件a,b本身為棧上分配的區域性變數,根物件a、b分別引用了物件A、B, 而B物件又引用了物件D,則GC開始前各物件的狀態如下圖所示:

初始狀態下所有物件都是白色的。
接著開始掃描根物件a、b; 由於根物件引用了物件A、B,那麼A、B變為灰色物件,接下來就開始分析灰色物件,分析A時,A沒有引用其他物件很快就轉入黑色,B引用了D,則B轉入黑色的同時還需要將D轉為灰色,進行接下來的分析。
灰色物件只有D,由於D沒有引用其他物件,所以D轉入黑色。標記過程結束
最終,黑色的物件會被保留下來,白色物件會被回收掉。
在這裡插入圖片描述

STW
stop the world是gc的最大效能問題,對於gc而言,需要停止所有的記憶體變化,即停止所有的goroutine,等待gc結束之後才恢復。

觸發
閾值:預設記憶體擴大一倍,啟動gc
定期:預設2min觸發一次gc,src/runtime/proc.go:forcegcperiod
手動:runtime.gc()
go gc
在這裡插入圖片描述

go gc
GO的GC是並行GC, 也就是GC的大部分處理和普通的go程式碼是同時執行的, 這讓GO的GC流程比較複雜.

Stack scan:Collect pointers from globals and goroutine stacks。收集根物件(全域性變數,和G stack),開啟寫屏障。全域性變數、開啟寫屏障需要STW,G stack只需要停止該G就好,時間比較少。
Mark: Mark objects and follow pointers。標記所有根物件, 和根物件可以到達的所有物件不被回收。
Mark Termination: Rescan globals/changed stack, finish mark。重新掃描全域性變數,和上一輪改變的stack(寫屏障),完成標記工作。這個過程需要STW。
Sweep: 按標記結果清掃span
目前整個GC流程會進行兩次STW(Stop The World), 第一次是Stack scan階段, 第二次是Mark Termination階段.

第一次STW會準備根物件的掃描, 啟動寫屏障(Write Barrier)和輔助GC(mutator assist).
第二次STW會重新掃描部分根物件, 禁用寫屏障(Write Barrier)和輔助GC(mutator assist).
從1.8以後的golang將第一步的stop the world 也取消了,這又是一次優化; 1.9開始, 寫屏障的實現使用了Hybrid Write Barrier, 大幅減少了第二次STW的時間.

寫屏障
因為go支援並行GC, GC的掃描和go程式碼可以同時執行, 這樣帶來的問題是GC掃描的過程中go程式碼有可能改變了物件的依賴樹。

例如開始掃描時發現根物件A和B, B擁有C的指標。

GC先掃描A,A放入黑色
B把C的指標交給A
GC再掃描B,B放入黑色
C在白色,會回收;但是A其實引用了C。
為了避免這個問題, go在GC的標記階段會啟用寫屏障(Write Barrier).

啟用了寫屏障(Write Barrier)後,在GC第三輪rescan階段,根據寫屏障標記將C放入灰色,防止C丟失。

作者:陳先生_9e91
連結:https://www.jianshu.com/p/8b0c0f7772da

Mysql

MySQL 效能調優的10個方法

https://www.cnblogs.com/chenshengqun/p/8875512.html

mysql各種鎖介紹

https://blog.csdn.net/mikewuhao/article/details/99304495

事務的隔離級別

https://blog.csdn.net/zhouym_/article/details/90381606

資料庫SQL語句效能分析

https://blog.csdn.net/qq_37465368/article/details/82938878

SQL語句效能分析

https://www.cnblogs.com/jingzaixin/p/11424066.html

Mongo

MongoDB實戰效能優化

https://www.cnblogs.com/swordfall/p/10427150.html

mongodb效能優化

https://www.cnblogs.com/ngy0217/p/11080787.html

ETCD

徹底搞懂etcd raft選舉、資料同步

https://www.cnblogs.com/sunsky303/p/11451755.html

RESTful API 設計指南 - 阮一峰的網路日誌

http://www.ruanyifeng.com/blog/2014/05/restful_api.html

Golang 的引用型別底層實現 - 知乎

https://zhuanlan.zhihu.com/p/111796041

相關文章