overcommit_memory文件指定了內核針對內存分配的策略,其值能夠是0、一、2。 node
0, 表示內核將檢查是否有足夠的可用內存供應用進程使用;若是有足夠的可用內存,內存申請容許;不然,內存申請失敗,並把錯誤返回給應用進程。
1, 表示內核容許分配全部的物理內存,而無論當前的內存狀態如何。
2, 表示內核容許分配超過全部物理內存和交換空間總和的內存git
jenkins_service@jenkinsservice:~/redis-3.0.1$ sudo sysctl vm.overcommit_memory=1github
vm.overcommit_memory = 1redis
THP(Transparent Huge Pages)是一個使管理Huge Pages自動化的抽象層。算法
目前須要注意的是,因爲實現方式問題,THP會形成內存鎖影響性能,尤爲是在程序不是專門爲大內內存頁開發的時候,簡單介紹以下:服務器
操做系統後臺有一個叫作khugepaged的進程,它會一直掃描全部進程佔用的內存,在可能的狀況下會把4kpage交換爲Huge Pages,在這個過程當中,對於操做的內存的各類分配活動都須要各類內存鎖,直接影響程序的內存訪問性能,而且,這個過程對於應用是透明的,在應用層面不可控制,對於專門爲4k page優化的程序來講,可能會形成隨機的性能降低現象。app
Redis Cluster 命令行socket
//集羣(cluster) 性能
開啓cluster的redis必須是空服務器測試
修改redis.conf開啓cluster
設置3個cluster
10.24.6.7:6379
10.24.6.4:6379
10.24.6.6:6379
啓動三個節點上的Redis服務器。此時,三個Redis服務器節點均會以Redis Cluster的方式開始運行,但並無自動構建集羣,由於三者還處於「我不認識你,你不屬於我」的狀態,它們每一個都是孤零零的Redis節點,或者是隻包含了一個節點的集羣。咱們能夠經過Redis客戶端鏈接到服務器查看它們的狀態,圖一給出了狀態查詢方法和查詢結果,其中cluster nodes命令用於查看當前Redis節點所屬的Redis集羣中的全部節點,而cluster info則用於查看當前Redis節點所屬的Redis集羣的總體狀態。由圖中咱們能夠看到,Redis集羣中僅包含一個Redis節點,也就是當前節點,整個集羣的狀態是fail。
經過上面的操做,咱們已經將三個各自爲政的Redis節點規劃到一個相同的集羣中,那麼咱們如今是否就已經完成了集羣搭建的全部工做了呢?非也!經過圖二中對集羣狀態的查看咱們能夠知道,當前集羣的狀態仍是fail,此時的Redis集羣是不工做的,沒法處理任何Redis命令。那麼集羣的狀態爲何仍是fail呢?本博主經過查看官方文檔說明找到了緣由所在,現摘錄原文以下:
The FAIL state for the cluster happens in two cases.
1) If at least one hash slot is not served as the node serving it currently is in FAIL state.
2) If we are not able to reach the majority of masters (that is, if the majorify of masters are simply in PFAIL state, it is enough for the node to enter FAIL mode).
很明顯,致使咱們的集羣處於fail狀態的緣由不是第二個條,也就是說至少有一個hash slot沒有被服務!稍微考慮一下,可不是!何止有一個hash slot沒有被服務,壓根兒就沒有Redis節點爲任何hash slot服務!衆所周知,Redis Cluster經過hash slot將數據根據主鍵來分區,因此一條key-value數據會根據算法自動映射到一個hash slot,可是一個hash slot存儲在哪一個Redis節點上並非自動映射的,是須要集羣管理者自行分配的。那麼咱們須要爲多少個hash slot分配Redis節點呢?根據源碼可知是16384個,即咱們要將16384個hash slot分配到集羣內的三個節點上。Redis中用於分配hash slot的命令有不少,其中包括cluster addslots、cluster delslots和cluster setslot。鑑於咱們如今是集羣的初始化階段,因此咱們能夠選擇cluster addslots來分配hash slot,該命令的語法爲cluster addslots slot1 [slot2] ... [slotN]。
每一個redis客戶端單獨分配本身負責的部分
修改內容以下:cda76a0a094d2ce624e33bed7f3c75689a4128fd :0 myself,master - 0 0 connected 0-5000(注意是在自身節點的描述,也就是包含了myself那一行的後面追加hash slot的範圍)。相似的,Redis Cluster Node2上nodes-6379.conf文件中追加5001-10000,Redis Cluster Node3上nodes-6379.conf文件中追加10001-16383。通過這樣的配置後,Redis Cluster Node1負責存儲0至5000之間的全部hash slots,Redis Cluster Node2負責存儲5001至10000之間的全部hash slots,Redis Cluster Node3負責存儲10001至16383的全部hash slots。
這裏所謂的搭建集羣,說白了就是讓以前啓動的三個Redis節點彼此連通,意識到彼此的存在,那麼如何作到這一點呢?答案就是cluster meet命令。該命令的做用就是將當前節點主動介紹給另一個節點認識,圖二給出了cluster meet命令的執行方法和執行效果,由圖中可知咱們使用cluster meet命令分別將Redis Cluster Node1介紹給了Redis Cluster Node2(節點IP地址爲192.168.32.3,運行端口爲6379)和Redis Cluster Node3(節點IP地址爲192.168.32.4,運行端口爲6379),以後咱們再次查看集羣節點和集羣狀態就能夠知道,三個節點已經成功合併到了同一個集羣中。
這裏找到了3個節點
查看10.24.6.6客戶端
至此,3個結點
搭建完成標識:
在集羣狀態顯示爲ok以後,咱們就能夠像在Redis單機版上同樣執行Redis命令了。
非集羣模式客戶端在cluster跳轉時會提示MOVED錯誤
from redis.sentinel import Sentinel
sentinel = Sentinel([('10.24.6.7', 26379)], socket_timeout=0.1)
master = sentinel.master_for('10.24.6.5master', socket_timeout=0.1)
print master
master.set('aaaaaaaaaaaaaaa', 'bar')
master.set('bbbbbbbbbbbbbbbb', 'bar')
print master.get('aaaaaaaaaaaaaaa')
print master.get('bbbbbbbbbbbbbbbb')
Traceback (most recent call last):
File "E:/HomeInternet/server/utest_workspace/utest_utils/utest_unit/__init__.py", line 23, in <module>
master.set('bbbbbbbbbbbbbbbb', 'bar')
File "build\bdist.win32\egg\redis\client.py", line 1055, in set
File "build\bdist.win32\egg\redis\client.py", line 565, in execute_command
File "build\bdist.win32\egg\redis\client.py", line 577, in parse_response
File "build\bdist.win32\egg\redis\sentinel.py", line 55, in read_response
File "build\bdist.win32\egg\redis\connection.py", line 574, in read_response
redis.exceptions.ResponseError: MOVED 9577 10.24.6.6:6379
集羣模式客戶端在跳轉時會自動進行結點轉向
https://github.com/Grokzen/redis-py-cluster
from rediscluster import StrictRedisCluster
startup_nodes = [{"host": "10.24.6.7", "port": "6379"}]
rc = StrictRedisCluster(startup_nodes=startup_nodes, decode_responses=True)
print rc.set("bbbbbbbbbbbbbbbb", "bar")
True
print rc.get("bbbbbbbbbbbbbbbb")
from redis.sentinel import Sentinel
from redisclusterimport StrictRedisCluster
sentinel = Sentinel([('10.24.6.7', 26379)], socket_timeout=0.1)
ip, port = sentinel.discover_master('10.24.6.5master')
rc = StrictRedisCluster(host=ip, port=port, decode_responses=True)
print rc.set("bbbbbbbbbbbbbbbb", "bar")
print rc.get("bbbbbbbbbbbbbbbb")