工藝品做網(wǎng)站網(wǎng)絡(luò)推廣公司
引言
在我們?nèi)粘i_發(fā)中 redis是我們開發(fā)業(yè)務(wù)場景中不可缺少的部分。Redis 憑借其內(nèi)存存儲和快速響應(yīng)的特點,廣泛應(yīng)用于緩存、消息隊列等各種業(yè)務(wù)場景。然而,隨著數(shù)據(jù)量的不斷增長,單節(jié)點的 Redis 因為內(nèi)存限制和并發(fā)能力的局限,逐漸難以支撐高并發(fā)的請求。為了解決這些問題,我們通常會采用 搭建Redis 集群方案來解決高并發(fā)下的限制問題。然而,Redis 集群的部署往往需要更高的資源投入,巨大的內(nèi)存需求和運維成本帶來了不小的壓力。除此之外,集群模式下的數(shù)據(jù)分片和一致性問題,也讓系統(tǒng)設(shè)計的復(fù)雜度大大增加。
在這種高并發(fā)、大流量的業(yè)務(wù)場景下,我們是否能夠在追求 Redis 高性能的同時,找到更經(jīng)濟(jì)高效的大數(shù)據(jù)解決方案呢?除了 Redis 集群方案外,今天我將介紹一種可以替代 Redis 集群的方案,也是我在以往開發(fā)中廣泛使用的一種數(shù)據(jù)結(jié)構(gòu)——Pika。Pika 在兼容 Redis API 的基礎(chǔ)上,將數(shù)據(jù)存儲在磁盤上,突破了內(nèi)存限制,尤其適合大數(shù)據(jù)存儲和高并發(fā)訪問的需求。
什么是 Pika?
Pika 是一種兼容 Redis 協(xié)議的高效存儲引擎,設(shè)計初衷就是為了解決 Redis 在大數(shù)據(jù)場景下因內(nèi)存限制而帶來的瓶頸問題。與 Redis 將數(shù)據(jù)存儲在內(nèi)存中的方式不同,Pika 將數(shù)據(jù)存儲在磁盤上,從而有效擴(kuò)展存儲容量,適應(yīng)大規(guī)模數(shù)據(jù)的需求。當(dāng) Redis 的內(nèi)存使用量超過 16 GiB 時,會面臨多種限制,如內(nèi)存容量受限、單線程阻塞、啟動恢復(fù)時間長、內(nèi)存硬件成本高、緩沖區(qū)容易填滿、一主多從故障時的切換成本高等。Pika 的出現(xiàn)并非為了替代 Redis,而是為了補充 Redis,以便在大數(shù)據(jù)場景下依然保持高性能。Pika 力求完全遵守 Redis 協(xié)議,繼承 Redis 便捷的運維設(shè)計,同時通過持久化存儲來突破 Redis 在數(shù)據(jù)量巨大時內(nèi)存容量不足的瓶頸。此外,Pika 支持通過 slaveof
命令進(jìn)行主從模式配置,支持全量和增量數(shù)據(jù)同步,方便在大數(shù)據(jù)和高可用場景下的靈活擴(kuò)展。
Pika 的兼容性
Pika 兼容 Redis 中的 string
、hash
、list
、zset
和 set
五大核心數(shù)據(jù)類型,能夠支持大部分與之相關(guān)的操作接口(兼容詳情可查閱官方文檔),實現(xiàn)了幾乎所有 Redis 的基本操作需求。這意味著,現(xiàn)有的 Redis 客戶端和命令都可以無縫遷移到 Pika 上使用,無需額外學(xué)習(xí)新的命令或語法。
Pika 的主從備份能力
與 Redis 一樣,Pika 支持通過 slaveof
命令進(jìn)行主從復(fù)制,提供可靠的備份和高可用性支持。同時,Pika 實現(xiàn)了全同步和部分同步機(jī)制,能夠在數(shù)據(jù)同步中做到既靈活又高效,確保數(shù)據(jù)一致性和穩(wěn)定性。這樣,Pika 既保留了 Redis 數(shù)據(jù)復(fù)制的優(yōu)勢,又在容量上擴(kuò)展了存儲空間,可以在不更改代碼的前提下快速接入生產(chǎn)環(huán)境。
為什么選擇 Pika?
Pika 提供了與 Redis 一致的使用體驗,且不需要額外的學(xué)習(xí)和開發(fā)成本。相較于 Redis,Pika 的優(yōu)勢體現(xiàn)在以下幾方面:
- 更大的存儲容量:Pika 通過磁盤存儲解決了 Redis 的內(nèi)存瓶頸問題,適合大規(guī)模數(shù)據(jù)場景。
- 無縫替換:Pika 兼容 Redis 絕大多數(shù)核心命令,因此在功能實現(xiàn)和操作上與 Redis 幾乎無異,用戶不必更改現(xiàn)有代碼或熟悉新的命令,即可將 Pika 集成到現(xiàn)有系統(tǒng)中。
- 高可用性和備份支持:Pika 支持主從復(fù)制、全同步和部分同步,確保數(shù)據(jù)可靠性和高并發(fā)訪問。
Pika 的適用場景
Pika 的設(shè)計非常適合以下幾種高容量、高并發(fā)的數(shù)據(jù)場景:
- 大數(shù)據(jù)量緩存:對于數(shù)據(jù)規(guī)模龐大的應(yīng)用,比如實時數(shù)據(jù)處理、日志收集和分析場景,Pika 的磁盤存儲使它能輕松應(yīng)對 TB 級數(shù)據(jù),不再受限于內(nèi)存容量。適用于金融、廣告、物聯(lián)網(wǎng)等需要存儲大量實時數(shù)據(jù)的行業(yè)。
- 高并發(fā)訪問場景:在流量密集型業(yè)務(wù)中,如電商、游戲和社交網(wǎng)絡(luò),Pika 能夠支持高并發(fā)訪問需求,與 Redis 一樣實現(xiàn)快速的數(shù)據(jù)讀寫,但在資源消耗上更經(jīng)濟(jì)。
- 長時間數(shù)據(jù)存儲:在日志存儲、歷史數(shù)據(jù)存儲等業(yè)務(wù)中,數(shù)據(jù)需要長時間保留,但訪問頻率相對較低。Pika 的磁盤持久化存儲方式為此類場景提供了低成本的替代方案,不會因數(shù)據(jù)量增加而導(dǎo)致內(nèi)存壓力上升。
- 分布式集群環(huán)境:對于需要高可用性的數(shù)據(jù)集群應(yīng)用,Pika 的主從復(fù)制和同步功能使其可以在分布式環(huán)境中穩(wěn)定運行,支持多節(jié)點備份和容災(zāi)切換,確保數(shù)據(jù)的高可靠性和一致性。
Pika使用用戶
Pika 已被各大公司廣泛采用,用于內(nèi)部部署,證明了其可擴(kuò)展性和可靠性。一些值得注意的使用實例包括:
- 360公司:內(nèi)部部署,規(guī)模10000+實例,單機(jī)數(shù)據(jù)量1.8TB。
- 微博:內(nèi)部部署,有10000+個實例。
- 喜馬拉雅(Xcache) :6000+實例,海量數(shù)據(jù)超過120TB。
- 個推 公司:內(nèi)部部署,300+實例,累計數(shù)據(jù)量超過30TB。
此外,迅雷、小米、知乎、好未來、快手、搜狐、美團(tuán)、脈脈等公司也在使用 Pika。有關(guān)完整用戶列表,可以參考 Pika 項目提供的官方列表。
這些在不同公司和行業(yè)的部署凸顯了 Pika 在處理大規(guī)模、大容量數(shù)據(jù)存儲需求方面的適應(yīng)性和有效性。
接下來,我將展示如何安裝 Pika,并進(jìn)行簡單的使用示例,以便快速上手并體驗 Pika 的性能。
安裝之前我們先看下官方給的安裝示例:安裝示例
我按照官方的安裝示例 安裝的是v4.0.1最新版本及之前版本。但是我一直未make或build成功。不知道是不是我自己環(huán)境的問題。
本文章采用下載安裝包的形式來安裝
-
首先我們?nèi)グ姹編煜螺d對應(yīng)版本的安裝包(我選擇是v3.3.0)
-
將安裝包上傳到
/usr/local/pika
目錄中,便于管理:sudo mkdir -p /usr/local/pika
-
然后解壓該安裝包
sudo tar -xvf pika-linux-x86_64-v3.3.0.tar.bz2
-
解壓完成后會生成一個
output
文件夾,接下來我們執(zhí)行命令啟動./output/bin/pika -c ./output/conf/pika.confb
-
我第一次啟動報錯了 報錯如下:
-
這個錯誤提示主要有兩個原因:1. Rsync 失敗:
pika_rsync_service.cc:48
報錯提示無法啟動rsync
服務(wù),可能是rsync
沒有安裝或者路徑配置有問題。
2. 端口綁定失敗:提示bind port 10221 failed
,表示 Pika 無法綁定端口10221
,可能是端口被占用,或者當(dāng)前用戶權(quán)限不足。 -
Pika 使用
rsync
進(jìn)行數(shù)據(jù)同步,請確保系統(tǒng)已安裝rsync
:sudo yum install -y rsync
安裝完成后,重新嘗試啟動 Pika。
-
使用以下命令檢查是否有其他進(jìn)程占用了
10221
端口:sudo lsof -i :10221
如果有其他進(jìn)程占用端口,可以嘗試停止占用端口的進(jìn)程,或者更改 Pika 的端口配置。
-
解決上面問題后 我嘗試重新啟動,可以看到已經(jīng)成功啟動:
啟動成功后我們另開一個窗口來測試操作簡單命令:
我們來大概看下安裝的Pika配置文件 在output/conf
下的pika.conf
:
# Pika port
port : 9221 # Pika 監(jiān)聽的端口# Thread Number
thread-num : 1 # 用于處理客戶端請求的工作線程數(shù)# Thread Pool Size
thread-pool-size : 12 # 線程池大小,用于處理并發(fā)任務(wù)# Sync Thread Number
sync-thread-num : 6 # 用于主從同步的線程數(shù)# Pika log path
log-path : ./log/ # 日志文件的存儲路徑# Pika db path
db-path : ./db/ # 數(shù)據(jù)庫文件的存儲路徑# Pika write-buffer-size
write-buffer-size : 268435456 # 寫緩沖區(qū)大小,單位為字節(jié)(256MB)# Pika timeout
timeout : 60 # 客戶端連接空閑超時時間,單位為秒# Requirepass
requirepass : # 設(shè)置管理員密碼,用于驗證高權(quán)限操作# Masterauth
masterauth : # 從節(jié)點連接主節(jié)點時的認(rèn)證密碼# Userpass
userpass : # 普通用戶連接的密碼# User Blacklist
userblacklist : # 黑名單用戶列表,拒絕指定用戶訪問# Pika instance mode [classic | sharding]
instance-mode : classic # Pika 的實例模式:classic 為多數(shù)據(jù)庫模式,sharding 為分片模式# Set the number of databases. Limited in [1, 8]
databases : 1 # 數(shù)據(jù)庫數(shù)量,僅在 classic 模式下有效# default slot number each table in sharding mode
default-slot-num : 1024 # 每張表的分片數(shù)量,僅在 sharding 模式下有效# replication num defines followers in a single raft group, limited in [0, 4]
replication-num : 0 # Raft 組中的從節(jié)點數(shù)量# consensus level defines confirms before commit to client
consensus-level : 0 # 主節(jié)點提交前需要的確認(rèn)數(shù)量,用于 Raft 一致性協(xié)議# Dump Prefix
dump-prefix : # 導(dǎo)出文件的前綴,用于數(shù)據(jù)持久化文件命名# daemonize [yes | no]
#daemonize : yes # 是否以守護(hù)進(jìn)程方式運行(后臺運行)# Dump Path
dump-path : ./dump/ # 數(shù)據(jù)導(dǎo)出路徑# Expire-dump-days
dump-expire : 0 # 數(shù)據(jù)導(dǎo)出的過期天數(shù)(0 表示不過期)# pidfile Path
pidfile : ./pika.pid # Pika 進(jìn)程 ID 文件路徑# Max Connection
maxclients : 20000 # 最大客戶端連接數(shù)# the per file size of sst to compact, default is 20M
target-file-size-base : 20971520 # 每個 SST 文件的目標(biāo)大小(20MB)# Expire-logs-days
expire-logs-days : 7 # 日志文件的過期天數(shù)# Expire-logs-nums
expire-logs-nums : 10 # 日志文件的最大數(shù)量# Root-connection-num
root-connection-num : 2 # root 用戶的最大連接數(shù)# Slowlog-write-errorlog
slowlog-write-errorlog : no # 慢查詢?nèi)罩臼欠駥懭脲e誤日志文件# Slowlog-log-slower-than
slowlog-log-slower-than : 10000 # 慢查詢記錄的時間閾值,單位為微秒# Slowlog-max-len
slowlog-max-len : 128 # 慢查詢?nèi)罩镜淖畲髼l數(shù)# Pika db sync path
db-sync-path : ./dbsync/ # 數(shù)據(jù)同步文件的存儲路徑# db sync speed(MB) max is set to 1024MB, min is set to 0
db-sync-speed : -1 # 主從同步的最大速度,單位為 MB/s,-1 表示無限制# The slave priority
slave-priority : 100 # 從節(jié)點的優(yōu)先級# network interface
#network-interface : eth1 # 網(wǎng)絡(luò)接口(可以指定特定的網(wǎng)卡)# replication
#slaveof : master-ip:master-port # 設(shè)置為從節(jié)點并指定主節(jié)點地址和端口# CronTask, e.g., 02-04/60 for compaction between 2-4am every day
#compact-cron : 3/02-04/60 # 壓縮任務(wù)計劃:在每周三的 2-4 點進(jìn)行壓縮# Compact-interval, e.g., 6/60 checks compaction every 6 hours
#compact-interval : # 壓縮間隔,單位為小時。比 compact-cron 優(yōu)先# sync window size for binlog between master and slave, default is 9000
sync-window-size : 9000 # 主從同步的 binlog 窗口大小# max connection read buffer size, default is 256MB
max-conn-rbuf-size : 268435456 # 最大讀取緩沖區(qū)大小###################
## Critical Settings
###################
# write_binlog [yes | no]
write-binlog : yes # 是否開啟 binlog 日志記錄# binlog file size: default is 100M, limited in [1K, 2G]
binlog-file-size : 104857600 # binlog 文件大小限制(100MB)# Use cache to store up to 'max-cache-statistic-keys' keys
max-cache-statistic-keys : 0 # 緩存的統(tǒng)計鍵的最大數(shù)量,0 表示關(guān)閉此功能# Trigger small compaction after deleting/overwriting keys
small-compaction-threshold : 5000 # 觸發(fā)小壓縮的操作次數(shù)閾值# Flush triggered if all live memtables exceed this limit
max-write-buffer-size : 10737418240 # 所有 memtables 的總內(nèi)存大小上限(10GB)# Limit some command response size
max-client-response-size : 1073741824 # 限制響應(yīng)大小的最大值(1GB)# Compression type supported [snappy, zlib, lz4, zstd]
compression : snappy # 數(shù)據(jù)壓縮類型# max-background-flushes: default is 1, limited in [1, 4]
max-background-flushes : 1 # 后臺刷新任務(wù)的最大數(shù)量# max-background-compactions: default is 2, limited in [1, 8]
max-background-compactions : 2 # 后臺壓縮任務(wù)的最大數(shù)量# Maximum cached open file descriptors
max-cache-files : 5000 # 緩存的最大打開文件描述符數(shù)量# max_bytes_for_level_multiplier: default is 10, can change to 5
max-bytes-for-level-multiplier : 10 # RocksDB 層次的最大字節(jié)數(shù)乘數(shù)# BlockBasedTable block_size, default 4k
# block-size: 4096 # 塊表的塊大小(4KB)# block LRU cache, default 8M, 0 to disable
# block-cache: 8388608 # LRU 塊緩存大小(8MB)# whether the block cache is shared among RocksDB instances
# share-block-cache: no # 是否在多個 RocksDB 實例之間共享塊緩存# whether index and filter blocks are in block cache
# cache-index-and-filter-blocks: no # 是否將索引和過濾塊放入塊緩存# bloomfilter of the last level will not be built if set to yes
# optimize-filters-for-hits: no # 是否優(yōu)化最后一層的布隆過濾器# Enables dynamic levels target size for compaction
# level-compaction-dynamic-level-bytes: no # 是否啟用動態(tài)級別的壓縮目標(biāo)大小
根據(jù)配置文件的配置項可以根據(jù)自己的需求更改
在每次啟動時手動執(zhí)行啟動命令既麻煩又不便于管理。為此,我們可以通過 Systemd 配置一個服務(wù),使 Pika 開機(jī)自啟并便于系統(tǒng)控制,提升管理效率。
配置啟動服務(wù)
-
創(chuàng)建 Pika 系統(tǒng)用戶
為了提高安全性,創(chuàng)建一個專用的系統(tǒng)用戶和用戶組來運行 Pika(在/usr/local/pika下執(zhí)行):
sudo groupadd --system pika sudo useradd -M -s /sbin/nologin -g pika -d /usr/local/pika pika
-
設(shè)置文件擁有者
chown -R pika:pika output
-
配置 Pika 作為 Systemd 服務(wù)
在
/usr/lib/systemd/system
目錄下創(chuàng)建pika.service
文件:cat > /usr/lib/systemd/system/pika.service <<EOF[Unit] Description=pika server Requires=network.target After=network.target[Service] User=pika Group=pika Type=forking WorkingDirectory=/usr/local/pika/output ExecStart=/usr/local/pika/output/bin/pika -c /usr/local/pika/output/conf/pika.conf Restart=always[Install] WantedBy=multi-user.target EOF
確保
WorkingDirectory
路徑是有效的目錄,并且已經(jīng)在系統(tǒng)中正確創(chuàng)建。根據(jù)您之前的路徑配置,將WorkingDirectory
修改為實際存在的路徑,例如:WorkingDirectory=/usr/local/pika/pika-v4.0.1
ExecStart=/usr/local/pika/pika-v4.0.1-alpha/output/pika -c /usr/local/pika/pika-v4.0.1-alpha/conf/pika.conf -
增加文件描述符限制
為確保高并發(fā)場景下的穩(wěn)定性,增加文件描述符的限制:
-
創(chuàng)建
pika.service.d
目錄:sudo mkdir -p /etc/systemd/system/pika.service.d
-
在該目錄下創(chuàng)建
limit.conf
文件:sudo cat > /etc/systemd/system/pika.service.d/limit.conf <<EOF [Service] LimitNOFILE=65536 EOF
-
啟動和管理 Pika 服務(wù)
完成配置后,可以使用以下命令來管理 Pika:
# 重新加載 systemd 配置文件 sudo systemctl daemon-reload # 啟動 Pika 服務(wù) sudo systemctl start pika# 設(shè)置 Pika 開機(jī)啟動 sudo systemctl enable pika # 檢查服務(wù)狀態(tài) sudo systemctl status pika
通過以上步驟,Pika 已成功安裝并配置為 systemd 服務(wù),支持自動啟動、停止和重啟管理,方便在生產(chǎn)環(huán)境中使用。這樣不僅簡化了管理,還提高了服務(wù)的穩(wěn)定性。
注意事項
在安裝和配置 Pika 后,以下幾點是需要特別注意的,以便更好地理解 Pika 的使用場景和性能表現(xiàn):
-
線程模型
Pika 是多線程設(shè)計,不同于 Redis 的單線程模型,這使得 Pika 能在大多數(shù)多核 CPU 環(huán)境下有效地處理更多的并發(fā)請求。這種設(shè)計更適合于大量數(shù)據(jù)的場景,尤其是在持久化存儲需求強烈的場合。 -
適用場景
- 大數(shù)據(jù)、高容量場景:Pika 在大數(shù)據(jù)和持久化存儲的場景下更具優(yōu)勢。例如,當(dāng) Redis 內(nèi)存超出 16GB 后可能出現(xiàn)瓶頸,Pika 則通過將數(shù)據(jù)存儲在磁盤上而不依賴于內(nèi)存,有效解決了存儲容量的限制問題。
- 寫密集型操作:在寫密集型操作時,Pika 的多線程設(shè)計使其在高并發(fā)寫入場景中表現(xiàn)更優(yōu)。
-
性能限制
雖然 Pika 在某些場景下優(yōu)于 Redis,但它并非在所有情況下都優(yōu)于 Redis,也不能完全取代 Redis。在高性能內(nèi)存操作和極低延遲需求的場景下,例如高速緩存、實時性極高的操作,Redis 的內(nèi)存操作速度更具優(yōu)勢。 -
主從同步和故障恢復(fù)
Pika 支持通過slaveof
命令配置主從關(guān)系,但其同步機(jī)制依賴于磁盤 I/O,可能會導(dǎo)致與 Redis 相比稍微較慢的同步速度。對于高頻數(shù)據(jù)變更或?qū)?shù)據(jù)實時性要求較高的場景,可能仍需要 Redis 提供更快的響應(yīng)。 -
存儲開銷
因為 Pika 依賴磁盤存儲,所以需要保證存儲空間充足并定期清理過期數(shù)據(jù)。過大的數(shù)據(jù)集可能會導(dǎo)致磁盤 I/O 增加,從而對系統(tǒng)的整體性能產(chǎn)生影響。 -
選擇依據(jù)
Pika 并不是 Redis 的完全替代品。在決定使用 Pika 或 Redis 時,最好結(jié)合業(yè)務(wù)場景:如果數(shù)據(jù)量較小且關(guān)注內(nèi)存操作的速度,Redis 更合適;而在持久化需求高、數(shù)據(jù)量大或關(guān)注磁盤存儲擴(kuò)展性的場景下,Pika 更適用。
最后
Pika 作為一種兼容 Redis 協(xié)議的高效存儲引擎,在大數(shù)據(jù)和持久化存儲需求的業(yè)務(wù)場景中,為 Redis 用戶提供了一個強有力的補充方案。Pika 通過將數(shù)據(jù)存儲在磁盤上,有效突破了 Redis 在內(nèi)存容量上的限制,同時保持了 Redis 的高效操作體驗和簡便的管理特性。得益于多線程設(shè)計,Pika 能在寫密集和大容量場景中表現(xiàn)優(yōu)異,尤其適合那些對數(shù)據(jù)持久化、擴(kuò)展性要求較高的場合。
然而,Pika 并非 Redis 的完全替代品。在需要極低延遲、以緩存為核心的場景中,Redis 仍然具備不可替代的優(yōu)勢。因此,選擇 Pika 或 Redis 需要結(jié)合具體的業(yè)務(wù)需求,權(quán)衡各自的優(yōu)缺點??傮w而言,Pika 在特定的應(yīng)用場景下能夠發(fā)揮重要作用,是 Redis 在大數(shù)據(jù)場景中的有益補充。希望通過本次配置和使用指南,大家能夠更好地理解 Pika 的特性和適用性,為項目需求提供更高效的解決方案。