10+款Redis容器化技術選型對比,K8S並非萬金油

{"type":"doc","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"今天將分享的內容分爲以下4個方面:"}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"一、緣起"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"二、介紹多樣的容器化技術"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"三、Redis介紹"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"四、Redis容器化方案的對比"}]}]}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"一、緣起"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"首先我們先聊一下爲什麼今天我會分享這個主題。我和朋友一起組織了一個 Redis技術交流羣,到現在已經經營了6年左右的時間,其中某一天在羣裏有一個小夥伴就拋出來一個問題:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/c4\/c4071681afdb390f28882af0e23ca56c.jpeg","alt":"圖片","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"他問大家線上的Redis有沒有使用Docker安裝?Docker使用Host的網絡模式、磁盤使用本地掛載模式這種方案怎麼樣?這裏的話我們暫時先不說這個方案如何,因爲在今天的分享之後,我相信大家對於這個方案應該會有一個更清晰的認識和評價。"}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"二、介紹多樣的容器化技術"}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"1、chroot和jails"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在容器化技術方面,其實歷史很久遠了。雖然我們現在用的容器化技術,或者說 k8s,還有云原生的概念是近幾年才火起來的,但是實際上就容器化技術的發展來說,其實是很早的了。比如說最早的時候來自chroot,chroot大家可能都用過,或者都有了解過,在1979年的時候它是來自Unix,它主要的功能是可以修改進程和子進程的\/。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"通過使用chroot達到什麼樣效果呢?使用chroot加某一個目錄,然後再啓動一個進程,那麼這個進程自己所看到的 \/ ,就是我們平時所說的 \/ 目錄,這個 \/ 就會是我們剛纔指定的文件夾,或者說剛纔指定的路徑。這樣子的話可以有效的保護我們操作系統上面的一些文件,或者說權限和安全相關的東西。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在2000年的時候,出現了一個新的技術,叫做jails,其實它已經具備了sandbox,就是沙箱環境的雛形。使用jails的話,可以讓一個進程或者說創建的環境擁有獨立的網絡接口和IP地址,而當我們提到使用jails的話,我們肯定會想到一個問題,就是如果你有了獨立的網絡接口和IP地址,這樣的話就不能發原始的套接字,通常跟原始的套接字接觸得比較多的就是我們使用的Ping命令。默認的情況下,這樣子是不允許使用原始的套接字的,而有自己的網絡接口和IP地址,這個感覺上就像是我們常用的虛擬機。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/22\/22b4c3c270bad6a6421dc4565ce04105.jpeg","alt":"圖片","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"2、Linux VServer和OpenVZ"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"接下來在2001年的時候,在Linux社區當中就出現了一個新的技術叫做Linux VServer。Linux VServer有時候可以簡寫成lvs,但是和我們平時用到的4層的代理lvs其實是不一樣的。它其實是對Linux內核的一種Patch,它是需要修改Linux內核,修改完成之後,我們可以讓它支持系統級的虛擬化,同時使用Linux VServer的話,它可以共享系統調用,它是沒有仿真開銷的,也就是說我們常用的一些系統調用、系統調用的一些函數都是可以共享的。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在2005年的時候,出現的一個新的技術—OpenVZ。OpenVZ其實和Linux VServer有很大的相似點,它也是對內核的一種Patch,這兩種技術最大的變化就是它對Linux打了很多的Patch,加了很多新的功能,但是在2005年的時候,沒有把這些全部都合併到Linux的主幹當中,而且在使用OpenVZ的時候,它可以允許每個進程可以有自己的\/proc或者說自己的\/sys。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"其實我們大家都知道在Linux當中,比如說啓動一個進程,你在他的\/proc\/self下面,你就可以看到進程相關的信息。如果你有了自己獨立的\/proc,其實你就可以達到和其他的進程隔離開的效果。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"接下來另外一個顯著的特點就是它有獨立的users和groups,也就是說你可以有獨立的用戶或者獨立的組,而且這個是可以和系統當中其他的用戶或者組獨立開的。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"其次的話OpenVZ是有商業使用的,就是有很多國外的主機和各種VPS都是用OpenVZ這種技術方案。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/b9\/b9c2bed12f69b2c319ef504d68c00203.jpeg","alt":"圖片","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"3、namespace 和 cgroups"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"到了2002年的時候,新的技術是namespace。在Linux當中我們有了新的技術叫做namespace,namespace可以達到進程組內的特定資源的隔離。因爲我們平時用到的namespace其實有很多種,比如說有PID、net等,而且如果你不在相同的namespace下面的話,是看不到其他進程特定的資源的。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"到了2013年的時候,產生了一個新的namespace的特性,就是user namespace。其實當有了user namespace,就和上文提到的OpenVZ實現的獨立用戶和組的功能是比較像的。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"對於namespace的操作當中,通常會有三種。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"1)Clone"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"可以指定子進程在什麼namespace下面。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"2)Unshare"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"它是與其他進程不共享的,unshare再加一個-net,就可以與其他的進程獨立開,不共享自己的net,不共享自己的網絡的namespace。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"3)Setns"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"就是爲進程設置 namespace。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"到了2008年,cgroups開始被引入到Linux內核當中,它可以用於隔離進程組的資源使用,比如說可以隔離CPU、內存、磁盤,還有網絡,尤其是他在2013年和user namespace進行了一次組合之後,並且進行了重新的設計,這個時候,就變得更現代化了,就像我們現在經常使用到的Docker的相關特性,其實都來自於這個時候。所以說cgroups和namespace構成現代容器技術的基礎。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/15\/159340bbed0c9cbcaad70199ee286570.jpeg","alt":"圖片","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"4、LXC 和 CloudFoundry"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在2008年的時候,新的一項技術叫做LXC, 我們也會叫他Linux Container(以下均簡稱LXC)。上文我們提到了很多容器化的技術,比如Linux VServer、OpenVZ,但是這些都是通過打Patch來實現的,而LXC是首個可以直接和上游的Linux內核共同工作的。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"LXC是可以支持特權容器的,意思就是說可以在機器上面去做uid map、gid map,去做映射,而且不需要都拿root用戶去啓動,這樣子就具備了很大的便利性。而且這種方式可以讓你的被攻擊面大大縮小。LXC支持的這幾種比較常規的操作,就是LXC-start,可以用來啓動container,LXC-attach就可以進入container當中。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"到2011年的時候,CloudFoundry開始出現了,他實際上是使用了LXC和 Warden這兩項技術的組合,在這個時候不得不提到的,就是他的技術架構是CS的模式,也就是說還有一個客戶端和server端,而 Warden容器,它通常是有兩層,一層是隻讀os的,就是隻讀的操作系統的文件系統,另外一層是用於應用程序和其依賴的非持久化的讀寫層,就是這兩層的組合。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"我們之前提到的技術,大多數都是針對於某一臺機器的,就是對於單機的。CloudFoundry它最大的不同就是它可以管理跨計算機的容器集羣,這其實就已經有了現代容器技術的相關特性了。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/b4\/b494108bddd663b778d41ca08a73f82c.png","alt":"圖片","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"5、LMCTFY和systemd-nspawn"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在2013年的時候, Google開源了自己的容器化的解決方案,叫做LMCTFY。這個方案是可以支持CPU、內存還有設備的隔離。而且它是支持子容器的,可以讓應用程序去感知到自己當前是處在容器當中的。另外還可以再爲自己創建一個子容器,但是隨着2013年發展之後,它逐漸發現只依靠自己不停的做這些技術,就相當於單打獨鬥,發展始終是有限的,所以它逐步的將自己的主要精力放在抽象和移植上,把自己的核心特性都移植到了libcontainer。而libcontainer之後就是Docker的運行時的一個核心,再之後就是被Docker捐到了OCI,再然後就發展到了runC。這部分內容我們稍後再詳細講解。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"大家都知道服務器它肯定是有一個 PID爲1的進程。就是它的初始進程、守護進程,而現代的操作系統的話,大多數大家都使用的是systemd,同樣systemd它也提供了一種容器化的解決方案,叫做 systemd-nspawn。這個技術的話,它是可以和systemd相關的工具鏈進行結合的。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"systemd除了有我們平時用到的systemctl之類的,還有systemd machine ctl,它可以去管理機器,這個機器支持兩種主要的接口,一種是管理容器相關的接口,另外一種是管理虛擬機相關的接口。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"而我們通常來講,就是說systemd提供的容器技術解決方案,它是允許我們通過machine ctl去容器去進行交互的,比如說你可以通過machine ctl start,去啓動一個systemd支持的容器,或者通過 machine ctl stop,去關掉它,而在這種技術下,它是支持資源還有網絡等隔離的,其實它最主要的是systemd ns,它其實是使用namespace去做隔離。對於資源方面是來自於systemd,systemd是可以使用cgroups去做資源隔離的,其實這也是這兩種兩種技術方案的組合。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/1b\/1b45882f0fa139cbcd4df00306053ad7.png","alt":"圖片","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"6、Docker"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"而在2013年Docker也出現了。通常來講,Docker是容器時代的引領者,爲什麼這麼說呢?因爲Docker在2013年出現的時候,他首先提到了標準化的部署單元,就是Docker image。同時它還推出了DockerHub,就是中央鏡像倉庫。允許所有人通過DockerHub去下載預先已經構建好的Docker image,並且通過一行Docker run就可以啓動這個容器。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在衆多使用起來比較繁瑣、比較複雜的技術下,Docker這時提出來,你只需要一行Docker run,就可以啓動一個容器,它大大簡化了大家啓動容器的複雜度,提升了便捷性。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"所以Docker這項技術就開始風靡全球。而Docker它主要提供的一些功能是什麼呢?比如說資源的隔離和管理。而且Docker在0.9之前,它的容器運行時是LXC,在0.9之後,他就開始把LXC替換掉,替換成了libcontainer,而這個libcontainer其實就是我們在上文提到的Google的 LMCTFY。再之後libcontainer捐給了OCI。而那之後Docker現在的容器運行時是什麼呢?是containerd。containerd的更下層是runc,runc的核心其實就是libcontainer。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"而到了2014年的時候, Google發現大多數的容器化解決方案,其實都只提供了單機的解決方案,同時由於Docker也是CS架構的,所以它需要有一個Docker demand,它是需要有守護進程存在的,而這個守護進程的話,是需要用root用戶去啓動的,而root用戶啓動的守護進程,其實是增加了被攻擊面,所以 Docker的安全問題也被很多人詬病。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在這個時候 Google就發現了這個點,並且把自己的Borg系統去做了開源,開源版本就是Kubernetes。Google還聯合了一些公司,組建了一個雲原生基金會(CNCF)。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/44\/4463f2980d62d71a35d13330a77ca5c8.png","alt":"圖片","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"7、Kubernetes"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"通常來講Kubernetes是雲原生應用的基石,也就是說在Kubernetes出現之後,我們的雲原生技術開始逐步地發展起來,逐步地引領了潮流,Kubernetes提供了一些主要的特性。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"它可以支持比較靈活的調度、控制和管理,而這個調度程序的話,除了它默認的以外,也可以比較方便的去對它做擴展,比如說我們可以自己去寫自己的調度程序,或者說親和性、反親和性,這些其實都是我們比較常用到的一些特性。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"還有包括他提供的一些服務,比如說內置的 DNS、kube-DNS或者說現在的CoreDNS,通過域名的方式去做服務發現,以及Kubernetes當中有很多的控制器。它可以將集羣的狀態調整至我們預期的狀態,就比如說有一個pod掛掉了,它可以自動的把它再恢復到我們預期想要的樣子。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"另外就是它支持豐富的資源種類,比如說幾個主要的層級,最小的是pod,再往上有deployment,或者有StatefulSets,類似於這樣子的資源。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"最後一點是它讓我們更加喜歡它的因素,就是它有豐富的CRD的拓展,即可以通過自己去寫一些自定義的資源,然後對它進行擴展,比如CRD。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/a8\/a8451bf64ebe1d9870e93b558bb2bad8.png","alt":"圖片","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"8、更多的容器化技術"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"除了剛纔我們提到的這些主要的技術以外,其實還有很多我們沒有提到的一些容器化的技術,比如說像runc,上文我們沒有太多的介紹,還有containerd。containerd其實也是Docker開源出來的自己的核心,他的目標是做一個標準化工業可用的容器運行時,還有CoreOS開源出來的解決方案叫做rkt。而rkt瞄準的點就是上文提到的Docker相關的安全問題。但是rkt現在項目已經終止了。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"還有紅帽(Red Hat)開源出來的 podman, podman是一種可以用它來啓動容器,可以用它去管理容器,而且沒有守護進程,所以就安全性來講的話,podman可以說比Docker的安全性直觀上來看的話會好一些,但是它的便捷性來講的話,就要大打折扣了。比如說容器的重啓、開機起之類的,但是我們都是有一些不同的解決方案的。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在2017年的時候,這個時候有一個 Kata Container,而這個Kata Container它有一段發展過程,最開始是英特爾,英特爾在搞自己的容器運行時,還有一家初創公司叫做hyper.sh,這家公司也在搞自己的容器運行時,這兩家公司瞄準的都是做更安全的容器,他們使用的底層的技術都是基於K8S。而之後這兩家公司做了合併,hyper.sh它開源出來的一個解決方案是runv,被英特爾看上了之後就誕生了 Kata Container。在2018年的時候,AWS開源出來自己的Firecracker。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"這兩項技術和我們上文提到的機器上的容器化技術其實大有不同,因爲它的底層其實相當於是虛擬機,而我們通常來講,都認爲它是輕量級虛擬機的一種容器化的技術。以上就是關於多樣的容器化技術的介紹。"}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"三、Redis介紹"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"接下來進入關於Redis相關的介紹,以下是從Redis的官網上面摘抄的一段介紹。"}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"1、Redis使用的主要場景"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"其實Redis現在是使用最廣泛的一種KV型數據庫。而我們在使用它的時候,主要的使用場景可能有以下幾種:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"把它當緩存使用,把它放在數據庫之前,把它當做緩存去使用;"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"把它當DB來用,這種就是需要把真正的拿它來存數據做持久化。"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"做消息隊列,它支持的數據類型也比較多,這裏就不再做介紹了。"}]}]}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"2、Redis的特點"}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"它是一個單線程的模型,它其實是可以有多個線程的,但是它的worker線程只有一個,在Redis6.0開始,它支持了io多線程,但io多線程只是可以有多線程去處理有網絡相關的部分,實際上你真正去處理數據還是單線程,所以整體而言,我們仍然把它叫做單線程模型。"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Redis的數據其實都在內存裏頭,它是一個內存型的數據庫。"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"與HA相關, Redis想要做HA,我們以前在做 Redis的HA主要靠Redis sentinel,而後面在Redis出來cluster之後,我們主要靠Redis cluster去做HA,這是兩種主要HA的解決方案。"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/d6\/d6c9fd4e1125a2e6b55facd91910e9be.png","alt":"圖片","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"四、Redis容器化方案的對比"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"當我們提到做 Redis運維相關的時候,我們有哪些需要考慮的點:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"部署,如何快速的部署,如何能夠快速的部署,而且還要去管理監聽的端口,讓端口不起衝突,還有日誌和持久化文件之類的,這部分都屬於部署相關的內容;"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"擴\/縮容,也是我們經常會遇到的問題;"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"監控和報警;"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"故障和恢復。"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"以上都是我們最關注的幾個方面。我接下來就對這幾個方面去做一些介紹。"}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"1、部署"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"當我們提到去做單機多實例的時候,Redis作單機多實例去部署的時候,首先第一點就是我們希望能夠有進程級別的資源隔離,我們某一個節點上面所有部署的Redis實例,可以有自己的資源,可以不受別的實例的影響,這就是對於進程級別的資源隔離。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"進程級別的資源隔離,它其實主要分爲兩個方面,一方面是CPU,另一方面是內存,其次的話我們希望在單機上面我們也可以有自己的端口管理,或者說我們可以有獨立的網絡資源隔離的相關的技術。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在這種情況下,首先我們提到說進程級別的資源隔離,我們介紹了那麼多的容器化相關技術,我們已經知道了,支持進程級別的資源隔離的話,有最簡單的一種方案就是用cgroups,如果想要去做網絡資源隔離的話,我們有namespace,也就是說所有支持cgroups和 namespace的這種計劃的解決方案,都可以滿足我們這個地方的需求。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"再有一種方案就是虛擬化的方案,也就是我們上文提到比如說Kata Container,Kata Container這種基於虛擬化的方式,因爲虛擬化的方案其實大家都有所接觸,大家都知道就是虛擬化的這種技術,其實默認情況下,剛開始全部都做隔離。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"所以對於部署而言,如果你使用的是比如說像Docker,比如說你想使用的像 systemd-nspawn這些它都可以既用到cgroups,又用到了 namespace,是都可以去用的,只不過是你需要考慮一些便捷性,比如說你如果是使用Docker的話,進行一個Docker命令跑過去,然後只要讓它映射到不同的端口,其實就結束了。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"如果你使用是systemd-nspawn,這樣子的話,你需要去寫一些配置文件。如果你要是去用一些虛擬化的解決方案的話,同樣的也需要去準備一些鏡像。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/7d\/7df5a847d0b5d5c5e008bf3851494e22.jpeg","alt":"圖片","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"2、擴\/縮容"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"關於擴\/縮容,其實會有兩種最主要的場景,一種場景就是單實例 maxmemory 調整,就是我們最大內存的調整。還有一種是對於我們的集羣化的集羣解決方案,就是Redis Cluster。對於這種集羣規模,我們有擴\/縮容的話,會有兩方面的變化。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"一方面是 Node,就是我們的節點的變更,如果會新增節點,也可能會去移除節點。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"另外一種就是Slot的變更,就是希望把我的 slot 去做一些遷移,當然這些和Node節點會是相關的,因爲當我們去做擴容的時候,我們把Redis Cluster當中的一些Node節點增多,增多了之後,就可以不給他分配Slot,或者說我想要讓某些Slot集中到某些節點上面,其實這些需求也是同樣存在的。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"那我們來看一下,如果你當時想要去做maxmemory的調整,如果我們是前提已經做了容器化,想通過 cgroups去對它做資源的限制,就需要有一個可以支持動態調整 cgroups配額的解決方案。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"比如說我們用到Docker update,它是可以直接修改某個實例,或者說其中的某一個容器的cgroups資源的一些限制,比如說我們可以Docker update,給它指定新的內存,可以限制它最大可用內存,當你把它的可用內存數調大,接下來你就可以對實例去調整它的 maxmemory ,也就是說對於單實例 maxmemory,其實最主要的就是需要有cgroups的技術,向cgroups的技術提供一些支持。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"對於集羣節點的變更的話,這個部分稍後再做詳細介紹。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/09\/0984b0abfc6578e1c6d5da7badf0423b.jpeg","alt":"圖片","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"3、監控報警"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"第三點就是監控報警,不管是使用物理機也好,或者使用雲環境也好,或者使用任何解決方案都好,監控報警我們最想要得到的效果就是,它可以自動發現。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"我們希望當啓動一個實例之後,我們就可以立馬知道這個實例A他已經起來了,並且知道他的狀態是什麼,而監控報警的話,這部分其實是不依賴於特定的容器化技術的,就即使是在純粹的物理機上部署,也可以通過一些解決方案自動的發現它,自動的把它註冊到我們的監控系統當中去,所以它是屬於監控報警的這部分,其實它是不依賴於特定的容器技術的,但唯一的一個問題就是說假如說使用了容器化的方案,可以讓常用的 Redis exporter,配合Prometheus去做監控,可以讓 Redis exporter和 Redis server,這兩個進程可以處於同一個網絡的命名空間。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"如果他們兩個處於同一個網絡的命名空間的話,可以直接通過127.0.0.1:6379,然後直接去聯通它,如果我們使用的是k8s的話,可以直接把它倆放到一個pod當中,但是這些都無關緊要,因爲它是不依賴於特定的容器化技術的,你可以使用任何你想要用的技術,都可以去做監控和報警。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/4f\/4fe1b4793de87c2ca4c4a2afac845d1d.jpeg","alt":"圖片","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"4、故障恢復"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"最後我們提到的部分是故障和恢復。在這個部分我認爲最主要的有三個方面:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"第一個是實例的重啓。"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"有可能在某些情況下,某些場景下,你的實例在運行過程當中它可能會宕掉,如果你想讓他自動重啓的話,你需要有一個進程管理的工具。對於我們而言,上文我們提到了systemd,systemd是可以支持對於某一個進程的自動拉起的,還可以支持進程掛掉之後自動拉起, 可以 restart,或者你使用Docker,它也有一個restart policy,可以指定他爲 always或者指定爲on-failure,然後讓它在掛掉的時候再把它給拉起來。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"如果你使用的是k8s,那麼就更簡單了,可以自動拉起來。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"第二個是主從切換。"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"主從切換相對來說是一個常態,但在這裏我也把它列到故障恢復當中,是因爲可能在主從切換的過程當中,有可能你的集羣狀況已經不健康了,是會有這種情況存在的。那主從切換的時候我們需要做什麼?第一方面,需要讓他能夠有數據的持久化,另一方面在主從切換的時候,有可能會遇到一種情況,就是資源不夠,導致主從切換失敗,在這種情況下,其實和我們上文前面提到的擴\/縮容其實是相關的,所以在這種情況下就必須得給他加資源,而最好的辦法是可以自動給他加資源。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在k8s當中,想要讓它自動加資源,我們通常會給他設置它的request和limit,就是資源的配額,希望它能自動的加起來,我們通常把他叫做vpa。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"第三個是數據恢復。"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"通常來講,比如說我們開了 RDB和AOF,而且希望我們的數據可以保存下來,以便於在我們數據恢復的時候可以直接開始使用。所以數據持久化也是一方面。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/34\/34523ccd51fcfd655debe822e6d66e12.jpeg","alt":"圖片","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"我們去做容器化的時候,我們需要考慮哪些點?如果說你是使用Docker的話,你需要去掛一個券,然後你可以把這個數據去做持久化,比如說你使用systemd-nspawn也需要有一個文件目錄去把這個數據做持續化。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"如果你使用的是k8s的話,在掛券的時候,你會有各種各樣的選擇,比如說你可以去掛 ceph的RDB、s3或者一個本地的某一個文件目錄。但是爲了更高的可靠性,可能會使用副本數更多的分佈式存儲。"}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"5、Node節點變更"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"接下來,我們來聊一下上文我們在提到服務擴\/縮容的時候,提到的關於Node節點變更,比如說我想要讓我的某一個Redis cluster,去擴充一些節點,擴充節點的時候,那就意味着你必須能夠加入集羣,能夠和集羣正常通信,這才說明你真正的加入到了集羣當中。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"而我們也知道在Redis cluster當中,你要去做集羣,最大的一個問題就是k8s,k8s當中做服務發現其實它都是大多數通過一個域名,而我們的Redis當中,比如說我們的NodeIP,它其實只支持IP,它並不支持我們的域名。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"所以如果說Node節點變更,需要做的事情就是允許我們動態地去把NodeIP寫到我們的集羣配置當中。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"如果想要讓它有一個完整的生命週期,以下截圖是來自於一個叫Kubedb的operator,在下圖中可以看到,Redis這個地方提供了最主要的三個部分:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"PVCs,PVCs就是做數據的持久化。"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Services,Services就是做服務發現。"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"StatefulSets,StatefulSets其實就是k8s當中的一種資源,而這資源它對於我們的有狀態應用會更友好一些。"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"其實在整個內容當中還有一點沒有介紹的是什麼呢?就是Redis背後的公司叫做Redis Labs,它提供了一種商業化的方案,就是Redis Enterprise一種解決方案。其實也是在k8s的解決方案之上的,也是用了Redis operator。他的方案和Kubedb這種方案基本類似,因爲核心還都是用的StatefulSets,然後再加上自己的Controller,去完成這個事情。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/32\/32718ecb7ab134309fb17dee34434d16.jpeg","alt":"圖片","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"五、總結 "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"我們來看一下今天的總結。如果是我們單機使用的話,我們可以交給Docker或者其他支持cgroups或者namespace資源管理的工具。因爲當你使用了cgroups、namespace的話,你可以做到資源的隔離,可以避免網絡的端口的衝突之類的事情都可以實現。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"而如果是像我在上文提到的小夥伴提到的那個問題:他打算使用主機的網絡,僅僅是想讓Docker去做一個進程管理,而且你也不希望引入新的內容。那麼systemd或者systemd-nspawn都是可以考慮的,因爲這也是容器化的解決方案。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"如果是在複雜場景下的調度和管理的話,比如想要有很大的規模,並且想要有更靈活的調度和管理,我推薦你使用的是Kubernetes operator,比如說Kubedb,其實也是一種解決方案。如果你的場景沒有那麼複雜,比較簡單,其實原生的Kubernetes StatefulSets稍微做一些調整和修改,也是可以滿足你的需求。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/0c\/0ce9d13186a02cbdd5711aefdb657b56.png","alt":"圖片","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"以上就是我今天分享的主要內容了,感謝大家的參與。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":">>>>"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"Q&A"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"Q1:請問Redis集羣假如用三臺物理機做,每臺運行2個實例,如何保障每臺物理機的實例不是互爲主從的?"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"A1 :"},{"type":"text","text":"這個問題其實我們通常情況下大家也都會遇到。第一點如果你是使用物理機來做,並且你每臺機器上面運行兩個實例,三臺機器每個機器上面運行2個實例,一共有6個實例。這6個實例你是否可以保證它每個互相都不爲主從的,其實是可以直接保證。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"唯一的問題就是假如說這是一個集羣,然後發生故障轉移,發生節點的主動切換,就非常有可能存在你的主從發生了變更。其實這個地方的話其實我更加建議,如果你發現了這種問題的話,你手動去做切換,因爲物理機環境去做這個事情,目前我還沒看到有什麼特別好的解決辦法。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"Q2 : 請問k8s 中擴容時,如何增加新節點。擴容和分配slot的步驟如何自動化的進行?"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"A2 :"},{"type":"text","text":"我們分開兩步來講,第一部分是增加新節點,增加新節點的話,剛纔我其實在過程裏頭已經提到了,增加完新的節點之後,首先你一定要讓它能夠和集羣去做通信,然而這個地方就是需要你去修改集羣的配置文件,然後你需要他有一個NodeIP,因爲之間是通過IP去做通信的,所以你需要去修改它的配置文件,把它的 NodeIP加進去,這樣子他纔可以和集羣當中的其他節點去做通信,然而這個部分的話,我更推薦的是用operator去做。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"Q3 : 請問如果不用Redis operator,也不使用分佈式存儲,k8s如何部署cluster集羣呢?"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"A3 :"},{"type":"text","text":"不用Redis operator其實也是可以的,剛纔我也介紹過,有兩種模式,一種模式就是用StatefulSets,這種模式的話相對來說會比較穩妥一些。同時它的最主要的部分仍然是修改配置,你需要在你的Redis的容器鏡像當中,你可以給它加一個init容器,然後可以在這個部分先給他做一次修改配置的操作,這是可以的。修改完配置的操作之後,再把它給拉起來,這樣子他纔可以加入到集羣當中。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"Q4 : 請問網絡延遲在不同網絡模型下有什麼區別?"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"A4 :"},{"type":"text","text":"如果我們直接使用物理機的網絡,通常來講,我們不認爲這種方式有延遲,就是主機網絡一般情況下我們會忽略掉它的延遲,但是如果你使用的是overlay的這種網絡模型的話,因爲它是覆蓋層的網絡,所以你在去做發包解包的時候,當然是會有不同的資源的損耗,性能的損耗都是有的。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"Q5 : 請問一般建議公司公用一個Redis集羣,還是各系統獨立集羣?"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"A5 :"},{"type":"text","text":"這個問題當然是建議各個系統獨立集羣了,我們來舉一個最簡單的例子,比如說你在其中用到了list,我們都知道Redis就有一個ziplist的配置項,他其實跟你的存儲和你的性能是有關係的。如果你是公司的所有的東西都用同一個集羣,那你修改了Redis集羣的配置的話,很可能會影響到所有的服務。但如果你是每個系統獨立用一個Redis羣的話,彼此之間互不影響,也不會出現某一個應用不小心把集羣給打掛了,然後造成連鎖反應的情況。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"Q6 : 請問Redis持久化,在生產中如何考慮呢?"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"A6 :"},{"type":"text","text":"這部分東西我是這樣想的。如果你真的需要去做持久化,一方面Redis提供了兩種核心,一種是 RDB,另外一種是AOF,如果說你的數據很多的話,相應你的RDB可能會變得很大。如果你是去做持久化,我通常建議就是兩個裏頭去做一次權衡。因爲通常來講,即使你是使用物理機的環境,我也建議你的存儲目錄可以放到一個獨立的盤裏頭,或者說你可以去掛在一個分佈式的存儲,但是前提是你需要保證它的性能,因爲你不能因爲它的寫入性能而拖累你的集羣,所以更加推薦的就是你可以全都把它們打開,但是如果你數據其實沒那麼重要,你可以你只開AOF。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"Q7 : 請問生產級別的ceph可靠不?"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"A7 :"},{"type":"text","text":"其實ceph的可靠性這個問題,很多人都討論過,就我個人而言,ceph的可靠性是有保證的。我這邊在用的ceph很多,並且存了很多比較核心的數據,所以ceph的可靠性是ok的。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"重點在於說你能不能搞得定他,而且有一家公司其實大家可能有所瞭解,叫做SUSE,就是一個Linux的一個發行版,這家公司其實提供了一個企業級的存儲解決方案,並且它的底層其實還是用的ceph,其實這也是正常的,只要有專人去搞這個事情,然後把它解決掉,我覺得ceph足夠穩定的。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"順便提一下,如果你使用的是k8s的話,現在有一個項目叫做rocket,它其實提供了一個ceph的operator,這種方案其實現在已經算是相對來說比較很穩定的了,推薦大家嘗試一下。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"Q8: 請問申請內存、限制內存、還有本身Redis內存怎麼配置比較好?"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"A8:"},{"type":"text","text":"這裏需要考慮幾個問題,首先我們先說Redis本身的內存,其實要看你的實際業務的使用場景,或者說你業務的實際需求,你肯定不可能讓你的Redis的實例或者Redis集羣的內存都佔滿。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"如果是佔滿的話,你就需要開啓lru去做驅逐之類的事情,這是一方面。另一方面就是申請內存,其實我理解你這個地方要問的問題應該是指,在k8s環境下面,在k8s下面一個是request的,一個是limit,limit肯定是你的可用限制的內存,限制內存你一定需要考慮到Redis本身還要用到的一些內存。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"嘉賓介紹:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"張晉濤,"},{"type":"text","text":"雲原生技術專家。"}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"負責DevOps的實踐和落地,推進容器化技術落地和運維自動化等。"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"參與了衆多知名開源項目,對Docker、Kubernetes及相關生態有大量生產實踐和深入源碼的研究。"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"本文轉載自:dbaplus社羣(ID:dbaplus)"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"原文鏈接:"},{"type":"link","attrs":{"href":"https:\/\/mp.weixin.qq.com\/s\/D-6mDsWkpD58R9bwdFw3bQ","title":"xxx","type":null},"content":[{"type":"text","text":"10+款Redis容器化技術選型對比,K8S並非萬金油"}]}]}]}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章