『壹』 分布式限流 redis-cell
redis 4.0 以後開始支持擴展模塊, redis-cell 是一個用rust語言編寫的基於令牌桶演算法的的限流模塊,提供原子性的限流功能,並允許突發流量,可以很方便的應用於分布式環境中。
令牌桶演算法的原理是定義一個按一定速率產生token的桶,每次去桶中申請token,若桶中沒有足歲隱梁夠的token則申請失敗,否則成功。在請求不多的情況下,桶中的token基本會飽和,此時若流量激增,並不會馬上拒絕請求,所以這種演算法允許一定的流量激增。
這幾個步驟可以採用redis提供的原生命令去實現,但是,但是,但是高並發的時候數據會不一致,所以 redis-cell 將這個過程原子化,完美解決了分布式環境下數據的一致性問題。
官方提供了安裝包和源碼編譯兩種方式,源碼編譯要安裝rust環境,比較復雜,這里介紹安裝包方式安裝:
執行完以上步驟就可以使用其提供的限流功能了。
該模塊只提供了一個命令: CL.THROTTLE
CL.THROTTLE test 100 400 60 3
test: redis key
100: 官方叫 max_burst ,沒理解什麼意思,其值為令牌桶的容量 - 1, 首次執行時令牌桶會默認填滿
400: 與下一個參數一起,表示在指定時間窗口內允許訪問的次數
60: 指定的時間窗口,單位:秒
3: 表示本次要申請的令牌數,不寫則默認為 1
以上命令表示 從一個初始值為100的令牌桶中取3個令牌,攜扒該令牌桶的速率限制為400次/60秒 。
1: 是否成功,0:成功,1:拒絕
2: 令牌桶的容量,大小為初始值+1
3: 當前令牌桶中可用的令牌
4: 若乎運請求被拒絕,這個值表示多久後才令牌桶中會重新添加令牌,單位:秒, 可以作為重試時間
5: 表示多久後令牌桶中的令牌會存滿
下面以一個速率稍慢一點的令牌桶來演示一下,連續快速執行以下命令:
通過命令可以看到,每次從桶中取出3個令牌,當桶中令牌不足時,請求被拒絕。
因為業務的原因(周末請求比平時多),最近公司的服務一到周末就嗝屁,消防群里忙的不可開交,有幾次跟redis有關系導致服務雪崩,後來架構那邊出建議各個業務組減少對其他服務的依賴。
一方面其他服務都不可靠,一方面一些核心業務不能做降級,並且公司日益壯大,服務太多,出錯排查的成本太大,基於這些原因,能在自己服務內解決的就不要依賴其他服務。
個人覺得,項目不大的,維護成本不高的話,可以採用 直接使用 redsi-cell ,否則可以考慮細粒度的控制到每個服務節點去限流,配合相應的負載均衡策略去實現。以上為個人理解,僅供參考。
『貳』 hadoop分布式部署(轉載)--賊靠譜
原文地址:https://blog.csdn.net/sjmz30071360/article/details/79889055
1. 集群搭建形式
Hadoop環境搭建分為三種形式:單機模式、偽分布式模式、完全分布模式
單機模式—— 在一台單機上運行,沒有分布式文件系統,而是直接讀寫本地操作系統的文件系統。
偽分布式—— 也是在一台單機上運行,但不同的是java進程模仿分布式運行中的各類節點。即一台機器上,既當NameNode,又當DataNode,或者說既是JobTracker又是TaskTracker。沒有所謂的在多台機器上進行真正的分布式計算,故稱為「偽分布式」。
完全分布式—— 真正的分布式,由3個及以上的實體機或者虛擬機組成的機群。一個Hadoop集群環境中,NameNode,SecondaryName和DataNode是需要分配在不同的節點上,也就需要三台伺服器。
前兩種模式一般用在開發或測試環境下,生產環境下都是搭建完全分布式模式。
從分布式存儲的角度來說,集群中的節點由一個NameNode和若干個DataNode組成,另有一個SecondaryNameNode作為NameNode的備份。
從分布式應用的角度來說,集群中的節點由一個JobTracker和若干個TaskTracker組成。JobTracker負責任務的調度,TaskTracker負責並行執行任務。TaskTracker必須運行在DataNode上,這樣便於數據的本地計算。JobTracker和NameNode則無須在同一台機器上。
2. 環境
操作系統:CentOS7(紅帽開源版)
機器:虛擬機3台,(master 192.168.0.104, slave1 192.168.0.102, slave2 192.168.0.101)
JDK:1.8(jdk-8u162-linux-x64.tar)
Hadoop:2.9.0(http://www.apache.org/dyn/closer.cgi/hadoop/common/hadoop-2.9.0/hadoop-2.9.0.tar.gz)
3. 搭建步驟
3.1 每台機器安裝&配置JDK(1台做好後,克隆出其它機器)
1) 創建目錄 mkdir /usr/java
2) 上傳jdk安裝包到 /usr/java/
3) 解壓 tar -xvf jdk-8u162-linux-x64.tar
4) 追加環境變數 vi /etc/profile
5) 使環境變數生效 source /etc/profile
6) 檢測jdk正確安裝 java -version
3.2 修改每台機器主機名(hostname)
hostnamectl set-hostname master (立即生效)
hostnamectl set-hostname slave1 (立即生效)
hostnamectl set-hostname slave2 (立即生效)
確認修改
3.3 修改每台機器/etc/hosts文件
vi /etc/hosts
修改其中1台,然後scp到其它機器
scp 文件名 遠程主機用戶名@遠程主機名或ip:存放路徑
scp hosts [email protected]:/etc/
scp hosts [email protected]:/etc/
修改完之後,互ping其它機器,能互ping則說明修改OK
ping -c 3 slave1 (※ 3表示發送 3 個數據包)
3.4 配置ssh,實現無密碼登錄
無密碼登錄,效果也就是在master上,通過ssh slave1或者ssh slave2就可以登錄對方機器,而不用輸入密碼。
1) 每台機器執行ssh-keygen -t rsa,接下來一路回車即可
執行ssh-keygen -t rsa主要是生成 密鑰 和 密鑰的存放路徑
我們用的root用戶,公鑰私鑰都會保存在~/.ssh下
2) 在master上將公鑰放到authorized_keys里,命令:cat id_rsa.pub > authorized_keys
3) 將master上的authorized_keys放到其它機器上
scp authorized_keys root@slave1:~/.ssh/
scp authorized_keys root@slave2:~/.ssh/
4) 測試是否成功
3.5 上傳&配置hadoop(配置完master後,將/usr/hadoop/整個目錄內容到其它機器)
1) 創建目錄 mkdir /usr/hadoop
2) 上傳hadoop安裝包hadoop-2.9.0.tar.gz到 /usr/hadoop/
3) 解壓 tar -xvf hadoop-2.9.0.tar.gz
4) 追加環境變數 vi /etc/profile(其它機器也要相應配置一次hadoop環境變數)
5) 使環境變數生效 source /etc/profile
6) 確認環境變數配置OK
7) 創建HDFS存儲目錄
cd /usr/hadoop
mkdir hdfs
cd hdfs
mkdir name data tmp
/usr/hadoop/hdfs/name --存儲namenode文件
/usr/hadoop/hdfs/data --存儲數據
/usr/hadoop/hdfs/tmp --存儲臨時文件
8) 修改/usr/hadoop/hadoop-2.9.0/etc/hadoop/hadoop-env.sh文件,設置JAVA_HOME為實際路徑
否則啟動集群時,會提示路徑找不到
9) 修改/usr/hadoop/hadoop-2.9.0/etc/hadoop/yarn-env.sh文件,設置JAVA_HOME為實際路徑
10) 配置/usr/hadoop/hadoop-2.9.0/etc/hadoop/core-site.xml
增加hadoop.tmp.dir 和 fs.default.name
11) 配置/usr/hadoop/hadoop-2.9.0/etc/hadoop/hdfs-site.xml
dfs.replication:默認值3
dfs.permissions:默認值為true,設置為true有時候會遇到數據因為許可權訪問不了;設置為false可以不要檢查許可權就生成dfs上的文件
12) 配置/usr/hadoop/hadoop-2.9.0/etc/hadoop/mapred-site.xml
cd /usr/hadoop/hadoop-2.9.0/etc/hadoop
cp mapred-site.xml.template mapred-site.xml
maprece.framework.name:指定maprece運行在yarn平台,默認為local
13) 配置/usr/hadoop/hadoop-2.9.0/etc/hadoop/yarn-site.xml
yarn.resourcemanager.hostname:指定yarn的resourcemanager的地址
yarn.nodemanager.aux-services:recer獲取數據的方式
yarn.nodemanager.vmem-check-enabled:意思是忽略虛擬內存的檢查,如果安裝在虛擬機上,這個配置很有用,配上去之後後續操作不容易出問題。如果是在實體機上,並且內存夠多,可以將這個配置去掉
14) 配置/usr/hadoop/hadoop-2.9.0/etc/hadoop/slaves文件,將裡面的localhost刪除,配置後內容如下:
15) 整個/usr/hadoop/目錄到其它機器
scp -r hadoop root@slave1:/usr/
scp -r hadoop root@slave2:/usr/
3.6 啟動Hadoop
1) 啟動之前需要格式化一下。因為master是namenode,slave1和slave2都是datanode,所以在master上運行
hadoop namenode -format
格式化成功後,可以看到在/usr/hadoop/hdfs/name目錄下多了一個current目錄,而且該目錄下有一系列文件,如下:
2) 執行啟動(namenode只能在master上啟動,因為配置在master上;datanode每個節點上都可以啟動)
執行 start-all.sh
master上執行jps,會看到NameNode, SecondaryNameNode, ResourceManager
其它節點上執行jps,會看到DataNode, NodeManager
3) 在wins上打開網頁,查看HDFS管理頁面 http://192.168.0.104:50070查看,提示無法訪問
在master上,執行以下命令關閉防火牆,即可訪問(為了能夠正常訪問node節點,最好把其它機器的防火牆也stop了)
systemctl stop firewalld.service
HDFS管理首頁
HDFS Datenodes頁
訪問Yarn管理頁: http://192.168.0.104:8088
4)通過主機名也可以訪問的設置
win7為例,需要將以下信息追加到C:\Windows\System32\drivers\etc\hosts文件中
192.168.0.104 master
192.168.0.102 slave1
192.168.0.101 slave2
Over!!!搭建成功!!!
4. 運行實例
cd /usr/hadoop/hadoop-2.9.0/share/hadoop/maprece
hadoop jar hadoop-maprece-examples-2.9.0.jar pi 5 10
。。。。。。
=====================================================
如果不關防火牆,子節點可能出現,輸入jps後只有jps一個進程,或者是缺進程的情況,關閉防火牆就好了。
『叄』 Redis的Setnx命令實現分布式鎖
首先,分布式鎖和我們平常講到的鎖原理基本一樣,目的就是確保在多個線程並發時,只有一個線程在同一刻操作這個業務或者說方法、變數。
在一個進程中,也就是一個jvm或者說應用中,我們很容易去處理控制,在 java.util 並發包中已經為我們提供了這些方法去加鎖,比如 synchronized 關鍵字或者 Lock 鎖,都可以處理。
但是如果在分布式環境下,要保證多個線程同時只有1個能訪問某個資源,就需要用到分布式鎖。這里我們將介紹用Redis的 setnx 命令來實現分布式鎖。
其實目前通常所說的 setnx 命令,並非單指redis的 setnx key value 這條命令,這條命令可能會在後期redis版本中刪除。
一般代指redis中對 set 命令加上 nx 參數進行使用, set 這個命令,目前已經支持這么多參數可選:
從 Redis 2.6.12 版本開始, SET 命令的行為可以通過一系列參數來修改:
注入bean
這里同時啟動5個線程並發往redis中存儲 lock 這個key(key可以自定義,但需要一致),同時設置10秒的過期時間。
setIfAbsent 這個函數實現的功能與 setnx 命令一樣,代表如果沒有這個key則set成功獲取到鎖,否則set失敗沒有獲取到鎖。
獲得鎖後進行資源的操作,最後釋放鎖。
執行效果 :
可以看到同時只有1個線程能夠獲取到鎖。
使用 setnx 命令方式雖然操作比較簡單方便,但是會有如下問題:
可以在叢肢再次獲取鎖時,如果鎖被佔用就get值,判斷值是否是當前線程存的隨機值,如果是則再次執行 set 命令重新上鎖;當然為了保證原子性這些操作都要用 lua 腳本來執行。
可以使用 while 循環重復執行 setnx 命令,並設置一個超時時間退出循環。
可以盡量把鎖自動過期的時間設的冗餘一些。但也不能絕橡徹底解決。
可以在刪除鎖的時候先get值,判斷值是否是當前線程存的隨機值,只有相同才執行滲宏世刪鎖的操作;當然也要使用 lua 腳本執行來保證原子性。
分布式鎖需要滿足的特性
綜上:使用 setnx 命令來實現分布式鎖並不是一個很嚴謹的方案,如果是Java技術棧,我們可以使用 Redisson 庫來解決以上問題,接下來的文章會介紹如何使用。
Redisson實現分布式鎖
Redlock實現分布式鎖
『肆』 python面試之分布式
主要用於分散壓力,所以分布式的服務都是部署在不同的伺服器上的,再將服務做集群
根據「分層」的思想進行拆分。
例如,可以將一個項目根據「三層架構」 拆分
然後再分開部署 :
根據業務進行拆分。
例如,可以根據業務邏輯,將「電商項目」拆分成 「訂單項目」、「用戶項目」和「秒殺項目」 。顯然這三個拆分後的項目,仍然可以作為獨立的項目使用。像這種拆分的方法,就成為垂直拆分
主要用於分散能力,主要是將服務的顆粒度盡量細化,且自成一脈,壓力這塊並不是其關注的點,所以多個微服務是可以部署在同一台伺服器上的
微服務可以理解為一種 非常細粒度的垂直拆分 。例如,以上「訂單項目」本來就是垂直拆分後的子項目,但實際上「訂單項目」還能進一步拆分為「購物項目」、「結算項目」和「售後項目」,如圖
現在看圖中的「訂單項目」,它完全可以作為一個分布式項目的組成元素,但就不適合作為微服務的組成元素了(因為它還能再拆,而微服務應該是不能再拆的「微小」服務,類似於「原子性」)
分布式服務需要提供給別的分布式服務去調用,單獨拆出來 未必外部可用
微服務自成一脈,可以系統內部調用,也可以單獨提供服務
為什麼需要用分布式鎖,見下圖
變數A存在三個伺服器內存中(這個變數A主要體現是在一個類中的一個成員變數,是一個有狀態的對象),如果不加任何控制的話,變數A同時都會在分配一塊內存,三個請求發過來同時對這個變數操作,顯然結果是不對的!即使不是同時發過來,三個請求分別操作三個不同內存區域的數據,變數A之間不存在共享,也不具有可見性,處理的結果也是不對的。
分布式鎖應該具備哪些條件:
1、在分布式系統環境下,一個方法在同一時間只能被一個機器的一個線程執行;
2、高可用的獲取鎖與釋放鎖;
3、高性能的獲取鎖與釋放鎖;
4、具備可重入特性;
5、具備鎖失效機制,防止死鎖;
6、具備非阻塞鎖特性,即沒有獲取到鎖將直接返回獲取鎖失敗
Redis性能高
命令簡單,實現方便
使用setnx加鎖,key為鎖名,value隨意不重復就行(一般用uuid)
給鎖添加expire時間,超過該時間redis過期(即自動釋放鎖)
設置獲取鎖的超時時間,若超過時間,則放棄獲取鎖
通過鎖名獲取鎖值
比較鎖值和當前uuid是否一致,一致則釋放鎖(通過delete命令刪除redis鍵值對)
2PC:two phase commit protocol,二階段提交協議,是一種強一致性設計。
同步阻塞(導致長久的資源鎖定) ,只有第一階段全部正常完成(返回失敗,回字返回超時都會返回 「准備失敗」 ),才會進入第二階段
因為協調者可能會在任意一個時間點(發送准備命令之前,發送准備命令之後,發送回滾事務命令之前,發送回滾事務命令之後,發送提交事務命令之前,發送提交事務命令之後)故障,導致資源阻塞。
T:try,指的是預留,即資源的預留和鎖定,注意是預留
C:confirm,指的是確認操作,這一步其實就是真正的執行了
C:cancel,指的是撤銷操作,可以理解為把預留階段的動作撤銷了
從思想上看和 2PC 差不多,都是先試探性的執行,如果都可以那就真正的執行,如果不行就回滾。
適用於對實時性要求沒那麼高的業務場景,如:簡訊通知
『伍』 分布式minio搭建指南
分布式Minio可以讓你將多塊硬碟(甚至在不同的機器上)組成一個對象存儲服務。由於硬碟分布在不同的節點上,分布式Minio避免了單點故障。
在大數據領域,通常的設計理念都是無中心和分布式的。Minio分布式模式可以幫助你搭建一個高可用的對象存儲服務,你可以使用這些存儲設備,而不用考慮其真實物理位置。
分布式Minio採用 糾刪碼來防範多個節點宕機和位衰減bit rot。
分布式Minio至少需要4個硬碟,使用分布式Minio自動引入了糾刪碼功能。
單機Minio服務存在單點故障,相反,如果是一個有N塊硬碟的分布式Minio,只要有N/2硬碟在線,你的數據就是安全的。不過你需要至少有N/2+1個硬碟來創建新的對象。
例如,一個16節點的Minio集群,每個節點16塊硬碟,就算8台伺服器宕機,這個集群仍然是可讀的,不過你需要9台伺服器才能寫數據。
注意,只要遵守分布式Minio的限制,你可以組合不同的節點和每個節點幾塊硬碟。比如,你可以使用2個節點,每個節點4塊硬碟,也可以使用4個節點,每個節點兩塊硬碟,諸如此類。
Minio在分布式和單機模式下,所有讀寫操作都嚴格遵守 read-after-write 一致性模型。
如果你了解Minio單機模式的搭建的話,分布式搭建的流程基本一樣,Minio服務基於命令行傳入的參數自動切換成單機模式還是分布式模式。
安裝Minio - Minio快速入門.
啟動一個分布式Minio實例,你只需要把硬碟位置做為參數傳給minio server命令即可,然後,你需要在所有其它節點運行同樣的命令。
注意
目錄創建
run:啟動腳本及二進制文件目錄;
data:數據存儲目錄;
/etc/minio:配置文件目錄;
集群啟動文件
配置為系統服務
將minio二進制文件上傳到/data/minio/run目錄
給所有涉及到的文件或目錄添加許可權!
集群啟動