redis主從集群搭建及容災部署

jopen 8年前發布 | 39K 次閱讀 Redis NoSQL數據庫

Redis 也用了一段時間了,記錄一下相關集群搭建及配置詳解,方便后續使用查閱。

提綱

l   Redis 安裝

l   整體架構

l   Redis 主從結構搭建

l   Redis 容災部署(哨兵 sentinel )

l   Redis 常見問題

Redis 安裝

發行版: CentOS-6.6 64bit

內核: 2.6.32-504.el6.x86_64

CPU : intel-i7 3.6G

內存: 2G

下載 redis ,選擇合適的版本

[root@rocket software]# wget http://download.redis.io/releases/redis-2.8.17.tar.gz

[root@rocket software]# cd redis-2.8.17

[root@rocket redis-2.8.17]# make

[root@rocket redis-2.8.17]# make test

cd src && make test

make[1]: Entering directory `/home/software/redis-2.8.17/src'

You need tcl 8.5 or newer in order to run the Redis test

make[1]: *** [test] Error 1

make[1]: Leaving directory `/home/software/redis-2.8.17/src'

make: *** [test] Error 2

make test 報錯,安裝 tcl

[root@rocket software]# wget http://prdownloads.sourceforge.net/tcl/tcl8.5.18-src.tar.gz

[root@rocket software]# tar -zxvf tcl8.5.18-src.tar.gz

[root@rocket software]# cd tcl8.5.18

[root@rocket tcl8.5.18]# cd unix/

[root@rocket unix]# ./configure;make;make test;make install

tcl 安裝成功,繼續測試 redis 的安裝情況

[root@rocket redis-2.8.17]# make test

……

Cleanup: may take some time... OK

make[1]: Leaving directory `/home/software/redis-2.8.17/src'

說明 redis 安裝正常

整體架構

整體架構圖

這里是本文所搭建集群的整體架構,使用主從結構 + 哨兵( sentinel )來進行容災。

目錄結構

Redis 主從結構搭建

搭建 redis master

拷貝可執行文件

[root@rocket master]# pwd

/usr/local/redisDB/master

[root@rocket master]# cp /home/software/redis-2.8.17/src/redis-cli .

[root@rocket master]# cp /home/software/redis-2.8.17/src/redis-server .

配置文件 redis.conf

# 守護進程模式
daemonize yes 

# pid file
pidfile /var/run/redis.pid

# 監聽端口
port 7003

# TCP接收隊列長度,受/proc/sys/net/core/somaxconn和tcp_max_syn_backlog這兩個內核參數的影響
tcp-backlog 511

# 一個客戶端空閑多少秒后關閉連接(0代表禁用,永不關閉)
timeout 0

# 如果非零,則設置SO_KEEPALIVE選項來向空閑連接的客戶端發送ACK
tcp-keepalive 60

# 指定服務器調試等級
# 可能值:
# debug (大量信息,對開發/測試有用)
# verbose (很多精簡的有用信息,但是不像debug等級那么多)
# notice (適量的信息,基本上是你生產環境中需要的)
# warning (只有很重要/嚴重的信息會記錄下來)
loglevel notice

# 指明日志文件名
logfile "./redis7003.log"

# 設置數據庫個數
databases 16

# 會在指定秒數和數據變化次數之后把數據庫寫到磁盤上
# 900秒(15分鐘)之后,且至少1次變更
# 300秒(5分鐘)之后,且至少10次變更
# 60秒之后,且至少10000次變更
save 900 1
save 300 10
save 60 10000


# 默認如果開啟RDB快照(至少一條save指令)并且最新的后臺保存失敗,Redis將會停止接受寫操作
# 這將使用戶知道數據沒有正確的持久化到硬盤,否則可能沒人注意到并且造成一些災難
stop-writes-on-bgsave-error yes

# 當導出到 .rdb 數據庫時是否用LZF壓縮字符串對象
rdbcompression yes

# 版本5的RDB有一個CRC64算法的校驗和放在了文件的最后。這將使文件格式更加可靠。
rdbchecksum yes

# 持久化數據庫的文件名
dbfilename dump.rdb

# 工作目錄
dir ./

# 當master服務設置了密碼保護時,slav服務連接master的密碼
masterauth 0234kz9*l

# 當一個slave失去和master的連接,或者同步正在進行中,slave的行為可以有兩種:
#
# 1) 如果 slave-serve-stale-data 設置為 "yes" (默認值),slave會繼續響應客戶端請求,
# 可能是正常數據,或者是過時了的數據,也可能是還沒獲得值的空數據。
# 2) 如果 slave-serve-stale-data 設置為 "no",slave會回復"正在從master同步
# (SYNC with master in progress)"來處理各種請求,除了 INFO 和 SLAVEOF 命令。
slave-serve-stale-data yes

# 你可以配置salve實例是否接受寫操作。可寫的slave實例可能對存儲臨時數據比較有用(因為寫入salve
# 的數據在同master同步之后將很容易被刪除
slave-read-only yes

# 是否在slave套接字發送SYNC之后禁用 TCP_NODELAY?
# 如果你選擇“yes”Redis將使用更少的TCP包和帶寬來向slaves發送數據。但是這將使數據傳輸到slave
# 上有延遲,Linux內核的默認配置會達到40毫秒
# 如果你選擇了 "no" 數據傳輸到salve的延遲將會減少但要使用更多的帶寬
repl-disable-tcp-nodelay no

# slave的優先級是一個整數展示在Redis的Info輸出中。如果master不再正常工作了,哨兵將用它來
# 選擇一個slave提升=升為master。
# 優先級數字小的salve會優先考慮提升為master,所以例如有三個slave優先級分別為10,100,25,
# 哨兵將挑選優先級最小數字為10的slave。
# 0作為一個特殊的優先級,標識這個slave不能作為master,所以一個優先級為0的slave永遠不會被
# 哨兵挑選提升為master
slave-priority 100


# 密碼驗證
# 警告:因為Redis太快了,所以外面的人可以嘗試每秒150k的密碼來試圖破解密碼。這意味著你需要
# 一個高強度的密碼,否則破解太容易了
requirepass 0234kz9*l 

# redis實例最大占用內存,不要用比設置的上限更多的內存。一旦內存使用達到上限,Redis會根據選定的回收策略(參見:
# maxmemmory-policy)刪除key
maxmemory 3gb

# 最大內存策略:如果達到內存限制了,Redis如何選擇刪除key。你可以在下面五個行為里選:
# volatile-lru -> 根據LRU算法刪除帶有過期時間的key。
# allkeys-lru -> 根據LRU算法刪除任何key。
# volatile-random -> 根據過期設置來隨機刪除key, 具備過期時間的key。 
# allkeys->random -> 無差別隨機刪, 任何一個key。 
# volatile-ttl -> 根據最近過期時間來刪除(輔以TTL), 這是對于有過期時間的key 
# noeviction -> 誰也不刪,直接在寫操作時返回錯誤。
maxmemory-policy volatile-lru

# 默認情況下,Redis是異步的把數據導出到磁盤上。這種模式在很多應用里已經足夠好,但Redis進程
# 出問題或斷電時可能造成一段時間的寫操作丟失(這取決于配置的save指令)。
#
# AOF是一種提供了更可靠的替代持久化模式,例如使用默認的數據寫入文件策略(參見后面的配置)
# 在遇到像服務器斷電或單寫情況下Redis自身進程出問題但操作系統仍正常運行等突發事件時,Redis
# 能只丟失1秒的寫操作。
#
# AOF和RDB持久化能同時啟動并且不會有問題。
# 如果AOF開啟,那么在啟動時Redis將加載AOF文件,它更能保證數據的可靠性。
appendonly no

# aof文件名
appendfilename "appendonly.aof"

# fsync() 系統調用告訴操作系統把數據寫到磁盤上,而不是等更多的數據進入輸出緩沖區。
# 有些操作系統會真的把數據馬上刷到磁盤上;有些則會盡快去嘗試這么做。
#
# Redis支持三種不同的模式:
#
# no:不要立刻刷,只有在操作系統需要刷的時候再刷。比較快。
# always:每次寫操作都立刻寫入到aof文件。慢,但是最安全。
# everysec:每秒寫一次。折中方案。 
appendfsync everysec

# 如果AOF的同步策略設置成 "always" 或者 "everysec",并且后臺的存儲進程(后臺存儲或寫入AOF
# 日志)會產生很多磁盤I/O開銷。某些Linux的配置下會使Redis因為 fsync()系統調用而阻塞很久。
# 注意,目前對這個情況還沒有完美修正,甚至不同線程的 fsync() 會阻塞我們同步的write(2)調用。
#
# 為了緩解這個問題,可以用下面這個選項。它可以在 BGSAVE 或 BGREWRITEAOF 處理時阻止主進程進行fsync()。
# 
# 這就意味著如果有子進程在進行保存操作,那么Redis就處于"不可同步"的狀態。
# 這實際上是說,在最差的情況下可能會丟掉30秒鐘的日志數據。(默認Linux設定)
# 
# 如果你有延時問題把這個設置成"yes",否則就保持"no",這是保存持久數據的最安全的方式。
no-appendfsync-on-rewrite yes

# 自動重寫AOF文件
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb

# AOF文件可能在尾部是不完整的(這跟system關閉有問題,尤其是mount ext4文件系統時
# 沒有加上data=ordered選項。只會發生在os死時,redis自己死不會不完整)。
# 那redis重啟時load進內存的時候就有問題了。
# 發生的時候,可以選擇redis啟動報錯,并且通知用戶和寫日志,或者load盡量多正常的數據。
# 如果aof-load-truncated是yes,會自動發布一個log給客戶端然后load(默認)。
# 如果是no,用戶必須手動redis-check-aof修復AOF文件才可以。
# 注意,如果在讀取的過程中,發現這個aof是損壞的,服務器也是會退出的,
# 這個選項僅僅用于當服務器嘗試讀取更多的數據但又找不到相應的數據時。
aof-load-truncated yes

# Lua 腳本的最大執行時間,毫秒為單位
lua-time-limit 5000

# Redis慢查詢日志可以記錄超過指定時間的查詢
slowlog-log-slower-than 10000

# 這個長度沒有限制。只是要主要會消耗內存。你可以通過 SLOWLOG RESET 來回收內存。
slowlog-max-len 128

# redis延時監控系統在運行時會采樣一些操作,以便收集可能導致延時的數據根源。
# 通過 LATENCY命令 可以打印一些圖樣和獲取一些報告,方便監控
# 這個系統僅僅記錄那個執行時間大于或等于預定時間(毫秒)的操作, 
# 這個預定時間是通過latency-monitor-threshold配置來指定的,
# 當設置為0時,這個監控系統處于停止狀態
latency-monitor-threshold 0

# Redis能通知 Pub/Sub 客戶端關于鍵空間發生的事件,默認關閉
notify-keyspace-events ""

# 當hash只有少量的entry時,并且最大的entry所占空間沒有超過指定的限制時,會用一種節省內存的
# 數據結構來編碼。可以通過下面的指令來設定限制
hash-max-ziplist-entries 512
hash-max-ziplist-value 64

# 與hash似,數據元素較少的list,可以用另一種方式來編碼從而節省大量空間。
# 這種特殊的方式只有在符合下面限制時才可以用
list-max-ziplist-entries 512
list-max-ziplist-value 64

# set有一種特殊編碼的情況:當set數據全是十進制64位有符號整型數字構成的字符串時。
# 下面這個配置項就是用來設置set使用這種編碼來節省內存的最大長度。
set-max-intset-entries 512

# 與hash和list相似,有序集合也可以用一種特別的編碼方式來節省大量空間。
# 這種編碼只適合長度和元素都小于下面限制的有序集合
zset-max-ziplist-entries 128
zset-max-ziplist-value 64

# HyperLogLog稀疏結構表示字節的限制。該限制包括
# 16個字節的頭。當HyperLogLog使用稀疏結構表示
# 這些限制,它會被轉換成密度表示。
# 值大于16000是完全沒用的,因為在該點
# 密集的表示是更多的內存效率。
# 建議值是3000左右,以便具有的內存好處, 減少內存的消耗
hll-sparse-max-bytes 3000

# 啟用哈希刷新,每100個CPU毫秒會拿出1個毫秒來刷新Redis的主哈希表(頂級鍵值映射表)
activerehashing yes

# 客戶端的輸出緩沖區的限制,可用于強制斷開那些因為某種原因從服務器讀取數據的速度不夠快的客戶端
client-output-buffer-limit normal 0 0 0
client-output-buffer-limit slave 256mb 64mb 60
client-output-buffer-limit pubsub 32mb 8mb 60

# 默認情況下,“hz”的被設定為10。提高該值將在Redis空閑時使用更多的CPU時,但同時當有多個key
# 同時到期會使Redis的反應更靈敏,以及超時可以更精確地處理
hz 10

# 當一個子進程重寫AOF文件時,如果啟用下面的選項,則文件每生成32M數據會被同步
aof-rewrite-incremental-fsync yes

啟動 master

[root@rocket master]# ./redis-server ./redis.conf

[root@rocket master]# ps axu|grep redis

root 24000   0.1   0.7 137356   7440 ?         Ssl   23:28    0:00 ./redis-server *:7003

使用客戶端連接測試

[root@rocket master]# ./redis-cli -a 0234kz9*l -p 7003

127.0.0.1:7003> select 1

OK

127.0.0.1:7003[1]> set name zhangsan

OK

127.0.0.1:7003[1]> get name

"zhangsan"

127.0.0.1:7003[1]> quit

可以看到, redis 啟動成功并且可以開始讀寫數據。

搭建 redis slave

slave 的配置和 master 基本一致,只需要修改相應的 pidfile ,端口,日志文件名,并配上 master 的地址和認證密碼。

配置文件 redis_slave.conf (和 redis master 差異的地方)

# pid file

pidfile /var/run/redis_slave.pid

# 監聽端口

port 8003

# 指明日志文件名

logfile "./redis8003.log"

# 設置當本機為 slav 服務時,設置 master 服務的 IP 地址及端口,在 Redis 啟動時,它會自動從 master 進行數據同步

slaveof 127.0.0.1 7003

# 當 master 服務設置了密碼保護時, slav 服務連接 master 的密碼

masterauth 0234kz9*l

啟動 slave 并查看數據同步情況

[root@rocket slave]# ./redis-server ./redis_slave.conf

[root@rocket slave]# ./redis-cli -a 0234kz9*l -p 8003

127.0.0.1:8003> select 1

OK

127.0.0.1:8003[1]> get name

"zhangsan"

可以看到, master 中設置的 key-value 已經成功同步過來。

Redis 容災部署(哨兵 Sentinel )

哨兵的作用

1. 監控:監控主從是否正常 2. 通知:出現問題時,可以通知相關人員 3. 故障遷移:自動主從切換 4. 統一的配置管理:連接者詢問 sentinel 取得主從的地址

Raft 分布式算法

1. 主要用途:用于分布式系統,系統容錯,以及選出領頭羊 2. 作者: Diego Ongaro ,畢業于哈佛 3. 目前用到這個算法的項目有: a. CoreOS : 見下面

b. ectd : a distributed, consistent shared configuration

c. LogCabin :

分布式存儲系統 d. redis sentinel : redis 的監控系統

Sentinel 使用的 Raft 算法核心 : 原則

1. 所有 sentinel 都有選舉的領頭羊的權利 2. 每個 sentinel 都會要求其他 sentinel 選舉自己為領頭羊 ( 主要由發現 redis 客觀下線的 sentinel 先發起選舉

)

3.

每個 sentinel 只有一次選舉的機會 4. 采用先到先得的原則 5. 一旦加入到系統了,則不會自動清除 ( 這一點很重要

, why?)

6.

每個 sentinel 都有唯一的 uid ,不會因為重啟而變更 7. 達到領頭羊的條件是 N/2 + 1 個 sentinel 選擇了自己 8. 采用配置紀元,如果一次選舉出現腦裂,則配置紀元會遞增,進入下一次選舉,所有 sentinel 都會處于統一配置紀元,以最新的為標準。

Raft 算法核心 : 可視圖

Raft Visualization ( 算法演示 )

Raft 分布式算法的應用

coreos: 云計算新星 Docker 正在以火箭般的速度發展,與它相關的生態圈也漸入佳境, CoreOS 就是其中之一。 CoreOS 是一個全新的、面向數據中心設計的 Linux 操作系統,在 2014 年 7 月發布了首個穩定版本,目前已經完成了 800 萬美元的 A 輪融資。

Sentinel 實現 Redis 容災部署

三哨兵架構

[root@rocket sentinel]# tree

.

── redis-cli

── redis-sentinel

── redis-server

── sentinel1

│   ├ ── sentinel1.conf

│ └── sentinel1.log

── sentinel2

│   ├ ── sentinel2.conf

│ └── sentinel2.log

└── sentinel3

    ├ ── sentinel3.conf

└── sentinel3.log

哨兵一配置 sentinel1.conf

# Example sentinel.conf

port <sentinel-port>

port 26371

守護進程模式

daemonize yes

指明日志文件名

logfile "./sentinel1.log"

工作路徑,sentinel一般指定/tmp比較簡單

dir ./

哨兵監控這個master,在至少quorum個哨兵實例都認為master down后把master標記為odown

(objective down客觀down;相對應的存在sdown,subjective down,主觀down)狀態。

slaves是自動發現,所以你沒必要明確指定slaves。

sentinel monitor TestMaster 127.0.0.1 7003 1

master或slave多長時間(默認30秒)不能使用后標記為s_down狀態。

sentinel down-after-milliseconds TestMaster 1500

若sentinel在該配置值內未能完成failover操作(即故障時master/slave自動切換),則認為本次failover失敗。

sentinel failover-timeout TestMaster 10000

設置master和slaves驗證密碼

sentinel auth-pass TestMaster 0234kz9*l

sentinel config-epoch TestMaster 15 sentinel leader-epoch TestMaster 8394

#除了當前哨兵, 還有哪些在監控這個master的哨兵

sentinel known-sentinel TestMaster 127.0.0.1 26372 0aca3a57038e2907c8a07be2b3c0d15171e44da5 sentinel known-sentinel TestMaster 127.0.0.1 26373 ac1ef015411583d4b9f3d81cee830060b2f29862

sentinel current-epoch 8394</pre>

哨兵二配置 sentinel2.conf

# Example sentinel.conf

port <sentinel-port>

port 26372

守護進程模式

daemonize yes

指明日志文件名

logfile "./sentinel2.log"

工作路徑,sentinel一般指定/tmp比較簡單

dir ./

哨兵監控這個master,在至少quorum個哨兵實例都認為master down后把master標記為odown

(objective down客觀down;相對應的存在sdown,subjective down,主觀down)狀態。

slaves是自動發現,所以你沒必要明確指定slaves。

sentinel monitor TestMaster 127.0.0.1 7003 1

master或slave多長時間(默認30秒)不能使用后標記為s_down狀態。

sentinel down-after-milliseconds TestMaster 1500

若sentinel在該配置值內未能完成failover操作(即故障時master/slave自動切換),則認為本次failover失敗。

sentinel failover-timeout TestMaster 10000

設置master和slaves驗證密碼

sentinel auth-pass TestMaster 0234kz9*l

sentinel config-epoch TestMaster 15 sentinel leader-epoch TestMaster 8394

#除了當前哨兵, 還有哪些在監控這個master的哨兵

sentinel known-sentinel TestMaster 127.0.0.1 26371 b780bbc20fdea6d3789637053600c5fc58dd0690 sentinel known-sentinel TestMaster 127.0.0.1 26373 ac1ef015411583d4b9f3d81cee830060b2f29862

sentinel current-epoch 8394</pre>

哨兵三配置 sentinel3.conf

# Example sentinel.conf

port <sentinel-port>

port 26373

守護進程模式

daemonize yes

指明日志文件名

logfile "./sentinel3.log"

工作路徑,sentinel一般指定/tmp比較簡單

dir ./

哨兵監控這個master,在至少quorum個哨兵實例都認為master down后把master標記為odown

(objective down客觀down;相對應的存在sdown,subjective down,主觀down)狀態。

slaves是自動發現,所以你沒必要明確指定slaves。

sentinel monitor TestMaster 127.0.0.1 7003 1

master或slave多長時間(默認30秒)不能使用后標記為s_down狀態。

sentinel down-after-milliseconds TestMaster 1500

若sentinel在該配置值內未能完成failover操作(即故障時master/slave自動切換),則認為本次failover失敗。

sentinel failover-timeout TestMaster 10000

設置master和slaves驗證密碼

sentinel auth-pass TestMaster 0234kz9*l

sentinel config-epoch TestMaster 15 sentinel leader-epoch TestMaster 8394

#除了當前哨兵, 還有哪些在監控這個master的哨兵

sentinel known-sentinel TestMaster 127.0.0.1 26371 b780bbc20fdea6d3789637053600c5fc58dd0690 sentinel known-sentinel TestMaster 127.0.0.1 26372 0aca3a57038e2907c8a07be2b3c0d15171e44da5

sentinel current-epoch 8394</pre>

sentinel 中查看所監控的 master 和 slave

[root@rocket sentinel]# ./redis-cli -p 26371

127.0.0.1:26371> SENTINEL masters

1) 1) "name"

    2) "TestMaster"

    3) "ip"

    4) "127.0.0.1"

    5) "port"

    6) "7003"

    7) "runid"

    8) "de0896e3799706bda49cb92048776e233841e25d"

    9) "flags"

   10) "master"

127.0.0.1:26371> SENTINEL slaves TestMaster

1) 1) "name"

    2) "127.0.0.1:8003"

    3) "ip"

    4) "127.0.0.1"

    5) "port"

    6) "8003"

    7) "runid"

    8) "9b2a75596c828d6d605cc8529e96edcf951de25d"

    9) "flags"

   10) "slave"

查看當前的 master

127.0.0.1:26371> SENTINEL get-master-addr-by-name TestMaster

1) "127.0.0.1"

2) "7003"

停掉 master ,查看容災切換情況

[root@rocket master]# ps axu|grep redis

root       24000   0.2   0.9 137356   9556 ?         Ssl   Jan12    0:30 ./redis-server *:7003      

root       24240   0.2   0.7 137356   7504 ?         Ssl   Jan12    0:26 ./redis-server *:8003            

root       24873   0.3   0.7 137356   7524 ?         Ssl   01:31    0:25 ../redis-sentinel *:26371         

root       24971   0.3   0.7 137356   7524 ?         Ssl   01:33    0:25 ../redis-sentinel *:26372         

root       24981   0.3   0.7 137356   7520 ?         Ssl   01:33    0:25 ../redis-sentinel *:26373         

root 24995   0.0   0.5   19404   5080 pts/2     S+    01:34    0:00 ./redis-cli -p 26371

root 25969   0.0   0.0 103252    844 pts/0     S+    03:33    0:00 grep redis

[root@rocket master]# kill -QUIT 24000

再查看 master , 發現已經 master 已經切換為原來的 slave

127.0.0.1:26371> SENTINEL get-master-addr-by-name TestMaster

1) "127.0.0.1"

2) "8003"

查看 sentinel 日志

啟動原來的 master , 發現變成了 slave

[root@rocket master]# ./redis-server ./redis.conf

127.0.0.1:26371> SENTINEL slaves TestMaster

1) 1) "name"

    2) "127.0.0.1:7003"

    3) "ip"

    4) "127.0.0.1"

    5) "port"

6) "7003"

發現主從發生了對調。

sentinel 自動發現

每個 Sentinel 都訂閱了被它監視的所有主服務器和從服務器的 __sentinel__:hello 頻道,查找之前未出現過的 sentinel ( looking for unknown sentinels )。當一個 Sentinel 發現一個新的 Sentinel 時,它會將新的 Sentinel 添加到一個列表中,這個列表保存了 Sentinel 已知的,監視同一個主服務器的所有其他 Sentinel 。

127.0.0.1:7003[1]> SUBSCRIBE __sentinel__:hello

Reading messages... (press Ctrl-C to quit)

1) "subscribe"

2) "__sentinel__:hello"

3) (integer) 1

1) "message"

2) "__sentinel__:hello"

3) "127.0.0.1,26373,7d919ccfb5752caf6812da2d0dba4ed0a528ceda,8436,TestMaster,127.0.0.1,7003,8436"

1) "message"

2) "__sentinel__:hello"

3) "127.0.0.1,26372,9eda79e93e6d1aa4541564ac28e3dc899d39e43b,8436,TestMaster,127.0.0.1,7003,8436"

1) "message"

2) "__sentinel__:hello"

3) "127.0.0.1,26371,8d63bebfbca9e1205a43bc13b52079de6015758e,8436,TestMaster,127.0.0.1,7003,8436"

Redis 常見問題

最大內存問題:要設置好最大內存,以防不停的申請內存,造成系統內存都被用完。

Fork 進程問題: 'vm.overcommit_memory = 1' 這一個選項要加到系統的配置中,防止 fork 因內存不足而失敗。

密碼問題:需要設置復雜一些,防止暴力破解。

來自: http://www.cnblogs.com/linuxbug/p/5131504.html

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!