新聞中心
在現(xiàn)代互聯(lián)網(wǎng)應(yīng)用開發(fā)中,數(shù)據(jù)是最為重要的核心資產(chǎn)之一。為了保證數(shù)據(jù)的高效使用和可靠性,開發(fā)者需要選擇一種高度可擴(kuò)展且易于管理的數(shù)據(jù)庫。Redis是一種使用內(nèi)存存儲的高性能鍵值對數(shù)據(jù)庫,具有極高的讀寫速度和多種數(shù)據(jù)結(jié)構(gòu)支持。同時,Redis也具有出色的可擴(kuò)展性、高可靠性和強(qiáng)大的數(shù)據(jù)處理能力,成為許多Web應(yīng)用中不可或缺的一部分。本文將重點(diǎn)介紹如何使用異步處理Redis數(shù)據(jù)庫,從而達(dá)到高效實(shí)現(xiàn)數(shù)據(jù)更新的目的。

為什么需要異步處理Redis數(shù)據(jù)庫
Redis數(shù)據(jù)庫的高度性能和多種數(shù)據(jù)結(jié)構(gòu)支持,使其成為許多Web應(yīng)用中的重要組件。然而,許多應(yīng)用在實(shí)際運(yùn)行中都面臨一個共同的問題:數(shù)據(jù)更新頻繁,而數(shù)據(jù)讀取卻較為稀少。在這種情況下,如果每次數(shù)據(jù)更新都需要同步地寫入Redis數(shù)據(jù)庫,那么就會給系統(tǒng)帶來極大的負(fù)擔(dān),導(dǎo)致系統(tǒng)性能下降,響應(yīng)延遲增加等不利后果。因此,使用異步處理Redis數(shù)據(jù)庫可以將數(shù)據(jù)更新操作放入任務(wù)隊列中,以達(dá)到減輕系統(tǒng)負(fù)擔(dān)的效果。
使用異步處理Redis數(shù)據(jù)庫的優(yōu)點(diǎn)
1.提高系統(tǒng)響應(yīng)速度和吞吐量
異步處理Redis數(shù)據(jù)庫將數(shù)據(jù)更新操作放入任務(wù)隊列中,避免了每次請求都需要同步地寫入Redis數(shù)據(jù)庫的過程。這可以減少對I/O資源的占用,提高系統(tǒng)響應(yīng)速度和吞吐量。
2.保證數(shù)據(jù)更新的可靠性
Redis數(shù)據(jù)庫是一個單線程的鍵值對數(shù)據(jù)庫,沒有強(qiáng)制的持久化機(jī)制。因此,如果在寫入Redis數(shù)據(jù)庫時發(fā)生異常,那么這個更新操作將不會成功,這將導(dǎo)致數(shù)據(jù)的丟失。異步處理Redis數(shù)據(jù)庫可以將異常處理放在任務(wù)隊列中,保證更新操作可靠地完成。
3.簡化系統(tǒng)架構(gòu)
異步處理Redis數(shù)據(jù)庫可以將數(shù)據(jù)更新操作與系統(tǒng)架構(gòu)解耦,從而更好地維護(hù)系統(tǒng),減少系統(tǒng)架構(gòu)的復(fù)雜性。
如何實(shí)現(xiàn)異步處理Redis數(shù)據(jù)庫
現(xiàn)有的Python異步處理框架中,最為成熟的為Celery。Celery是Python異步任務(wù)隊列的解決方案,廣泛應(yīng)用于Web開發(fā)、數(shù)據(jù)處理以及分布式計算等領(lǐng)域。它實(shí)現(xiàn)了多任務(wù)調(diào)度和異步處理,并且支持多種后臺消息隊列,包括redis、RabbitMQ等。下面,我們將以Celery為例,介紹如何實(shí)現(xiàn)異步處理Redis數(shù)據(jù)庫。
1.安裝Celery
在使用Celery之前,需要先安裝Celery庫和redis后端庫。
“`
pip install celery
pip install redis
“`
2.配置Celery
在配置Celery之前,需要對Celery進(jìn)行初始化。通常情況下,在工程目錄下創(chuàng)建一個名為tasks.py的Python模塊,用于存放Celery任務(wù)。在tasks.py模塊中,定義一個名為celery的Celery實(shí)例,并在其中添加broker地址和任務(wù)存儲地址。
“`
from celery import Celery
app = Celery(‘tasks’, broker=’redis://localhost:6379/0′, backend=’redis://localhost:6379/1′)
“`
3.定義任務(wù)
在tasks.py模塊中,我們可以定義一個名為update_redis的任務(wù)。該任務(wù)用于將用戶的更新數(shù)據(jù)寫入Redis數(shù)據(jù)庫。
“`
from tasks import app
from redis import StrictRedis
redis = StrictRedis(host=’localhost’)
@app.task
def update_redis(user_id, data):
redis.set(user_id, data)
“`
其中,@app.task是一個裝飾器,用于告訴Celery該函數(shù)是一個任務(wù)。任務(wù)函數(shù)的參數(shù)可以包括任意數(shù)量的參數(shù),例如在本例中,任務(wù)函數(shù)的參數(shù)為user_id和data。任務(wù)函數(shù)中可以包括任何需要異步執(zhí)行的代碼。
4.調(diào)度任務(wù)
完成任務(wù)定義后,就可以在Python代碼中調(diào)度任務(wù)了。例如,我們可以在視圖函數(shù)中調(diào)用任務(wù)函數(shù),并將其異步執(zhí)行。這里使用apply_async方法實(shí)現(xiàn)異步調(diào)用。
“`
from tasks import update_redis
update_redis.apply_async(args=[user_id, data])
“`
使用apply_async函數(shù)調(diào)用任務(wù)函數(shù)時,可以傳入任意數(shù)量的參數(shù),這些參數(shù)將作為任務(wù)函數(shù)的參數(shù)傳入。Celery將負(fù)責(zé)將任務(wù)加入任務(wù)隊列,并異步執(zhí)行任務(wù)。
異步處理Redis數(shù)據(jù)庫是保證Web應(yīng)用性能和可靠性的重要手段之一。使用Python異步任務(wù)隊列框架Celery,可以輕松地將數(shù)據(jù)更新操作放入任務(wù)隊列中,避免了每次請求都需要同步地寫入Redis數(shù)據(jù)庫的過程,提高了系統(tǒng)響應(yīng)速度和吞吐量,保證了數(shù)據(jù)更新的可靠性,并且簡化了系統(tǒng)架構(gòu)。有了異步處理Redis數(shù)據(jù)庫的技巧,您的Web應(yīng)用程序可以更高效地使用Redis數(shù)據(jù)庫,提高性能和可靠性。
成都網(wǎng)站建設(shè)公司-創(chuàng)新互聯(lián),建站經(jīng)驗豐富以策略為先導(dǎo)10多年以來專注數(shù)字化網(wǎng)站建設(shè),提供企業(yè)網(wǎng)站建設(shè),高端網(wǎng)站設(shè)計,響應(yīng)式網(wǎng)站制作,設(shè)計師量身打造品牌風(fēng)格,熱線:028-86922220什么是Redis?
REmote DIctionary Server(Redis) 是一個由Salvatore Sanfilippo寫的key-value存儲系統(tǒng)
Redis是一個開源的使用ANSIC語言編寫、遵守BSD協(xié)議、支持網(wǎng)絡(luò)、可基于內(nèi)存亦可持久化的日志型、Key-Value數(shù)據(jù)庫,并提供多種語言的API
它通常被稱為數(shù)據(jù)結(jié)構(gòu)服務(wù)器,因為值(value)可以是 字符串(String), 哈希(Map), 列表斗信(list), (sets)和有序(sorted sets)等類型
Redis 簡介
Redis是完全開源免費(fèi)的,遵守BSD協(xié)議,是一個高性能的key-value數(shù)據(jù)庫
Redis與其他key – value緩存產(chǎn)品有以下三個特點(diǎn):
①Redis支持?jǐn)?shù)據(jù)的持久化,可以將內(nèi)存中的數(shù)據(jù)保存在磁盤中,重啟的時候可以再次加載進(jìn)行使用。
②Redis不僅僅支持簡單的key-value類型的數(shù)據(jù),同時還提供list,set,zset,hash等數(shù)據(jù)結(jié)構(gòu)的存儲。
③Redis支持?jǐn)?shù)據(jù)的備份,即master-slave模式的數(shù)據(jù)備份。
Redis 的特點(diǎn)
高性能:Redis 將所有數(shù)據(jù)集存儲在內(nèi)存中,可以在入門級 Linux 機(jī)器中每秒寫(SET)11 萬次,讀(GET)8.1 萬次
持久化:當(dāng)所有數(shù)據(jù)都存在于內(nèi)存中時,可以根據(jù)自上次保存以來經(jīng)過的時間和/或更新次數(shù),使用靈活的策略將更改異步保存在磁盤上
數(shù)據(jù)結(jié)構(gòu):Redis 支持各種類型的數(shù)據(jù)結(jié)構(gòu),例如字符串、散列、、列表、帶有范圍查詢的有序集、位圖、超級日志和帶有半徑查詢的地理空間索引
原子操作:處理不同數(shù)據(jù)類型的 Redis 操作是原子操作,因此可以安全地 SET 或 INCR 鍵,添加和刪除中的元素等
支持的語言:Redis 支持許多語言,如C、C++、Erlang、Go、Haskell、滑燃Java、JavaScript(Node.js)、Lua、Objective-C、Perl、PHP、Python、R、Ruby、Rust、Scala、Smalltalk等
主/從復(fù)制:Redis 遵循非常簡單快速的主/從復(fù)制。配置文件中只需要一行來設(shè)置它,而 Slave 在 Amazon EC2 實(shí)例上完成 10 MM
key 集的初始同步只需要 21 秒
分片:Redis 支持分片。與其他鍵值存儲一樣,跨多個 Redis 實(shí)例分發(fā)數(shù)據(jù)集非常容易
可移植:Redis 是用 C 編寫的,信銷虛適用于大多數(shù) POSIX 系統(tǒng),如 Linux、BSD、Mac OS X、Solaris 等
redis 就是一個族碧春數(shù)據(jù)庫,不過與傳統(tǒng)數(shù)據(jù)庫不同的是慧旁 redis 的數(shù)據(jù)是存在內(nèi)存和部分文件中的,所以讀寫速度非??欤虼?redis 被廣泛應(yīng)用于緩存方向。另外,redis 也經(jīng)常用來做分布式鎖。redis 提供了多種
數(shù)據(jù)類型
來支持不同的業(yè)務(wù)場景。除此之外,兆耐redis 支持事務(wù) 、持久化、LUA腳本、LRU驅(qū)動事件、多種集群方案。
Redis是由意大利人Salvatore Sanfilippo(網(wǎng)名:antirez)開發(fā)的一款內(nèi)存檔叢高速緩存數(shù)據(jù)庫。Redis全稱為:Remote Dictionary Server(遠(yuǎn)程數(shù)據(jù)服務(wù)),該軟件使用C語言編寫,Redis是一個key-value存儲系冊老統(tǒng),它支持豐富的數(shù)據(jù)類型,如:州蠢升string、list、set、zset(sorted set)、hash。
redis主從復(fù)制更好采用哪種結(jié)構(gòu)
redis主從復(fù)制總結(jié)整理
主題 Redis
Redis的主從復(fù)制策略是通過其持久化的rdb文件來實(shí)現(xiàn)的,其過程是先dump出rdb文件,將rdb文件全量傳輸給slave,然后再將dump后的操作實(shí)時同步到slave中。讓從服務(wù)器(slave server)成為主服務(wù)器(master server)的精確復(fù)制品。官方文檔ReplicationHowto中提到以下特點(diǎn):
一個master支持多個slave,slave可以接受其他slave的連接,作為其他slave的master,從而形成一個master-slave的多級結(jié)構(gòu)
復(fù)制功能不會阻塞主服務(wù)器: 即使有一個或多個從服務(wù)器正在進(jìn)行初次同步, 主服務(wù)器也可以繼續(xù)處理命令請求。復(fù)制功能不會阻塞從服務(wù)器: 只要在 redis.conf 文件中進(jìn)行了相應(yīng)的設(shè)置, 即使從服務(wù)器正在進(jìn)行初次同步, 服務(wù)器也可以使用舊版本的數(shù)據(jù)集來處理命令查詢。不過, 在從服務(wù)器刪除舊版本數(shù)據(jù)集并載入新版本數(shù)據(jù)集的那段時間內(nèi), 連接請求會被阻塞。
復(fù)制被利用來提供可擴(kuò)展性,比如可以將slave端用作數(shù)據(jù)冗余,也可以將耗時的命令(比如sort)發(fā)往某些slave從而避免master的阻塞,另外也可以用slave做持久稿宏化,由從服務(wù)器去執(zhí)行持久化操作,這只需要將master的配置文件中的save指令注首好釋掉。
Redis 使用異步復(fù)制。 從 Redis 2.8 開始, 從服務(wù)器會以每秒一次的頻率向主服務(wù)器報告復(fù)制流的處理進(jìn)度。
復(fù)制功能的實(shí)現(xiàn)
redis的主從復(fù)制分為兩個階段:
1)同步操作:將從服務(wù)器的數(shù)據(jù)庫狀態(tài)更新至主服務(wù)器當(dāng)前所處的數(shù)據(jù)庫狀態(tài)。
2)命令傳播:在主服務(wù)器的數(shù)據(jù)庫狀態(tài)被修改,導(dǎo)致主從服務(wù)器的數(shù)據(jù)庫狀態(tài)出現(xiàn)不一致時,讓主從服務(wù)器重新回到一致狀態(tài)。
同步
當(dāng)客戶端向從服務(wù)器發(fā)送 SLAVEOF 命令, 要求從服務(wù)器復(fù)制主服務(wù)器時, 從服務(wù)器首先需要執(zhí)行同步操作, 也即是, 將從服務(wù)器的數(shù)據(jù)庫狀態(tài)更新至主服務(wù)器當(dāng)前所處的數(shù)據(jù)庫狀態(tài)。
從服務(wù)器對主服務(wù)器的同步操作需要通過向主服務(wù)器發(fā)送 SYNC 命令來完成, 以下是 SYNC 命令的執(zhí)行步驟:
從服務(wù)器向主服務(wù)器發(fā)送 SYNC 命令。
收到 SYNC 命令的主服務(wù)器執(zhí)行 BGSAVE 命令, 在后臺生成一個 RDB 文件, 并使用一個緩沖區(qū)記錄從現(xiàn)在開始執(zhí)行的所有寫命令。
當(dāng)主服務(wù)器的 BGSAVE 命令執(zhí)行完畢時, 主服務(wù)器會將 BGSAVE 命令生成的 RDB 文件發(fā)送給從服務(wù)器, 從服務(wù)器接收并載入這個 RDB 文件, 將自己的數(shù)據(jù)庫狀態(tài)更新至主服務(wù)器執(zhí)行 BGSAVE 命令時的數(shù)據(jù)庫狀態(tài)。
主服務(wù)器將記錄在緩沖區(qū)里面的所有寫命令發(fā)送給從服務(wù)器, 從服務(wù)器執(zhí)行這些寫命令, 將自己的數(shù)據(jù)庫狀態(tài)更新至主服務(wù)器數(shù)據(jù)庫當(dāng)前所處的狀態(tài)。
下圖展示了 SYNC 命令執(zhí)行期間, 主從服務(wù)器的通信過程:
命令傳播
在同步操作執(zhí)行完畢之后, 主從服務(wù)器兩者的數(shù)據(jù)庫達(dá)到一致狀態(tài), 但這種一致并不是一成不變的。當(dāng)主服務(wù)器執(zhí)行客戶端發(fā)送的寫命令時,主服務(wù)器的數(shù)據(jù)庫就有可能會被修改, 并導(dǎo)致主從服務(wù)器狀態(tài)不再一致。為了讓主從服務(wù)器再次回到一致狀態(tài),主服務(wù)器需要對從服務(wù)器執(zhí)行命令傳播操作: 主服務(wù)器會將自己執(zhí)行的寫命令 —— 即造成主從服務(wù)器不一致的那條寫命令發(fā)送給從服務(wù)器執(zhí)行, 當(dāng)從服務(wù)器執(zhí)行了相同的寫命令之后, 主從服務(wù)器將再次回到一致狀態(tài)。但是這樣的復(fù)制功能有缺陷:在主從服務(wù)器斷線重連之后執(zhí)行同步動作時,生成完整的RDB文件并且發(fā)送到從服務(wù)器載入,但主從服務(wù)器的數(shù)據(jù)庫狀態(tài)在斷線前基本上是一致的,不一致的部分只有斷線后主服務(wù)器執(zhí)行那一部分修改數(shù)據(jù)庫的命令,所以這時SYNC命令就非常浪費(fèi),因為生成RDB文件時一個非常消耗CPU、內(nèi)存和IO資源的過程,發(fā)送RDB文件到從服務(wù)器會占用大量的網(wǎng)絡(luò)帶寬資源,從服務(wù)器在載入RDB文件的過程中會阻塞不會響應(yīng)任何命令,所以大部分情況下執(zhí)行SYNC命令是沒有必要也是非常不合理的。
為了解決2.8之前版本SYNC命令的性能問題,2.8版本設(shè)計了一個新的命令PSYNC,PSYNC命令分為 完整重同步 和 部分重同步 ,完整重同步過程用于從服務(wù)器初始化時鍵芹冊初次復(fù)制的情況和SYNC命令基本一致,PSYNC則用于斷線后重新復(fù)制,在條件允許的情況下,它不會生成RDB文件,而是給從服務(wù)器回復(fù)一個+Continue表示執(zhí)行部分重同步,并且把從服務(wù)器斷線后主服務(wù)器執(zhí)行的修改數(shù)據(jù)庫的命令發(fā)送到從服務(wù)器,從服務(wù)器執(zhí)行這些命令同步數(shù)據(jù)庫。
部分重同步功能由下面幾個部分構(gòu)成:
主服務(wù)器的復(fù)制偏移量 和 從服務(wù)器的復(fù)制偏移量 :當(dāng)主服務(wù)器在向從服務(wù)器進(jìn)行命令同步時,主服務(wù)器和從服務(wù)器會各自記錄一個復(fù)制偏移量,當(dāng)主從服務(wù)器的數(shù)據(jù)庫狀態(tài)一致時這兩個復(fù)制偏移量是相同的,如果這兩個偏移量不一致說明當(dāng)前主從服務(wù)器的狀態(tài)不一致。
主服務(wù)器的復(fù)制積壓緩沖區(qū) :復(fù)制積壓緩沖區(qū)是一個固定大小的FIFO隊列,當(dāng)隊列已滿時會彈出最早插入的數(shù)據(jù),在主服務(wù)器進(jìn)行命令傳播時會同時把命令放到緩沖區(qū)中,緩沖區(qū)包含兩部分?jǐn)?shù)據(jù),偏移量和字節(jié)。在進(jìn)行復(fù)制時從服務(wù)器會將偏移量上報到主服務(wù)器,主服務(wù)檢查當(dāng)前偏移量是否還存在緩沖區(qū)中,如果存在進(jìn)行部分重同步,如果不存在進(jìn)行完整重同步。因為這個積壓緩沖區(qū)是一個固定大小的隊列,所以當(dāng)從服務(wù)器長時間斷線時,從服務(wù)器的復(fù)制偏移量很可能已不再緩沖區(qū)中,這時候只能進(jìn)行完整重同步。
服務(wù)器的運(yùn)行ID :初次同步時主服務(wù)器會把ID發(fā)給從服務(wù)器,從服務(wù)器保存主服務(wù)器ID,當(dāng)斷線重連后,會把之前保存的主服務(wù)器ID上報給主服務(wù)器,主服務(wù)器檢查從服務(wù)器之前復(fù)制的主服務(wù)器ID是否和自己的ID相同,如果相同,執(zhí)行部分重同步,如果不同說明從服務(wù)器之前記錄的狀態(tài)不是當(dāng)前主服務(wù)器,這時候需要執(zhí)行完整重同步。
PSYNC命令實(shí)現(xiàn)
初始復(fù)制或者之前執(zhí)行過SLAVEOF no one命令,執(zhí)行完整重同步:發(fā)送PSYNC ? -1命令到主服務(wù)器。如果從服務(wù)器已經(jīng)復(fù)制過某個主服務(wù)器,在開始新復(fù)制時向主服務(wù)器發(fā)送PSYNC 命令,runid是上次復(fù)制的主服務(wù)器id,offset是從服務(wù)器的復(fù)制偏移量,主服務(wù)器會根據(jù)這個兩個參數(shù)來決定做哪種同步,判斷服務(wù)器id是否和本機(jī)相同,復(fù)制偏移量是否在緩沖區(qū)中,主服務(wù)器有三種回復(fù):
回復(fù)+FULLRESYNC 執(zhí)行完整重同步,從服務(wù)器把offset當(dāng)做初始復(fù)制偏移量
回復(fù)+CONTINUE,表示執(zhí)行部分重同步,從服務(wù)器等待主服務(wù)器發(fā)送缺少的數(shù)據(jù)
回復(fù)-ERR,表示主服務(wù)器版本低于2.8,不支持PSYNC命令
新版本復(fù)制過程:
設(shè)置主服務(wù)器地址和端口,通過調(diào)用SAVEOF 命令。
建立套接字連接。
發(fā)送PING命令,檢查主從服務(wù)器是否能夠正常處理命令。
身份驗證,從服務(wù)器設(shè)置了masterauth并且主服務(wù)器設(shè)置了requirepass是需要進(jìn)行身份驗證。這兩個選項要么都設(shè)置要么都不設(shè)置,如果只設(shè)置了一個從服務(wù)器向主服務(wù)器發(fā)送命令時會報錯。
發(fā)送端口信息,通過執(zhí)行命令REPLCONF listening-port ,向主服務(wù)器發(fā)送從服務(wù)器的監(jiān)聽端口號。
同步,從服務(wù)器向主服務(wù)器發(fā)送PSYNC命令。
命令傳播,完成同步之后主服務(wù)器會把之后執(zhí)行的寫命令傳播到從服務(wù)器保證主從服務(wù)器的狀態(tài)一致。
心跳檢測
在命令傳播階段,從服務(wù)器默認(rèn)每秒一次的頻率向主服務(wù)器發(fā)送命令:REPLCONF ACK ,replication_offset是從服務(wù)器的復(fù)制偏移量,該命令有三個作用:
檢測從服務(wù)器的網(wǎng)絡(luò)連接狀態(tài),檢測主從服務(wù)器連接是否正常,如果主服務(wù)器超過一定時間沒有收到從服務(wù)器的REPLCONF ACK 命令,那么它們的連接可能出了問題。
輔助實(shí)現(xiàn)min-slaves選項,min-slaves-to-write和min-slaves-max-lag兩個選項可以防止主服務(wù)器在不安全的情況下執(zhí)行寫命令,min-slaves-to-write 3 min-slaves-max-lag 10 表示如果從服務(wù)器少于3個,或者3個從服務(wù)器的延遲都大于10秒時,主服務(wù)器拒絕寫命令。
檢測命令丟失,主服務(wù)器接收到從服務(wù)器的REPLCONF ACK 命令之后會檢查從服務(wù)器的偏移量是否和主服務(wù)器的一致,如果不一致會把積壓緩沖區(qū)中的從服務(wù)器偏移量后面的命令發(fā)送到從服務(wù)器。
關(guān)閉主服務(wù)器持久化時,復(fù)制功能的數(shù)據(jù)安全
當(dāng)配置Redis復(fù)制功能時,強(qiáng)烈建議打開主服務(wù)器的持久化功能。 否則的話,由于延遲等問題,部署的服務(wù)應(yīng)該要避免自動拉起。為了幫助理解主服務(wù)器關(guān)閉持久化時自動拉起的危險性,參考一下以下會導(dǎo)致主從服務(wù)器數(shù)據(jù)全部丟失的例子:
假設(shè)節(jié)點(diǎn)A為主服務(wù)器,并且關(guān)閉了持久化。 并且節(jié)點(diǎn)B和節(jié)點(diǎn)C從節(jié)點(diǎn)A復(fù)制數(shù)據(jù)
節(jié)點(diǎn)A崩潰,然后由自動拉起服務(wù)重啟了節(jié)點(diǎn)A. 由于節(jié)點(diǎn)A的持久化被關(guān)閉了,所以重啟之后沒有任何數(shù)據(jù)
節(jié)點(diǎn)B和節(jié)點(diǎn)C將從節(jié)點(diǎn)A復(fù)制數(shù)據(jù),但是A的數(shù)據(jù)是空的, 于是就把自身保存的數(shù)據(jù)副本刪除。
在關(guān)閉主服務(wù)器上的持久化,并同時開啟自動拉起進(jìn)程的情況下,即便使用Sentinel來實(shí)現(xiàn)Redis的高可用性,也是非常危險的。 因為主服務(wù)器可能拉起得非??欤灾劣赟entinel在配置的心跳時間間隔內(nèi)沒有檢測到主服務(wù)器已被重啟,然后還是會執(zhí)行上面的數(shù)據(jù)丟失的流程。無論何時,數(shù)據(jù)安全都是極其重要的,所以應(yīng)該禁止主服務(wù)器關(guān)閉持久化的同時自動拉起。
只讀從服務(wù)器
從 Redis 2.6 開始, 從服務(wù)器支持只讀模式, 并且該模式為從服務(wù)器的默認(rèn)模式。
只讀模式由 redis.conf 文件中的 slave-read-only 選項控制, 也可以通過 CONFIG SET 命令來開啟或關(guān)閉這個模式。
只讀從服務(wù)器會拒絕執(zhí)行任何寫命令, 所以不會出現(xiàn)因為操作失誤而將數(shù)據(jù)不小心寫入到了從服務(wù)器的情況。
即使從服務(wù)器是只讀的, DEBUG 和 CONFIG 等管理式命令仍然是可以使用的, 還是不應(yīng)該將服務(wù)器暴露給互聯(lián)網(wǎng)或者任何不可信網(wǎng)絡(luò)。 不過, 使用 redis.conf 中的命令改名選項, 可以通過禁止執(zhí)行某些命令來提升只讀從服務(wù)器的安全性。
一些不重要的臨時數(shù)據(jù), 仍然是可以保存在從服務(wù)器上面的。 比如說, 客戶端可以在從服務(wù)器上保存主服務(wù)器的可達(dá)性信息, 從而實(shí)現(xiàn)故障轉(zhuǎn)移策略。所以仍然要讓一個從服務(wù)器變得可寫。
從服務(wù)器相關(guān)配置
如果主服務(wù)器通過 requirepass 選項設(shè)置了密碼, 那么為了讓從服務(wù)器的同步操作可以順利進(jìn)行, 我們也必須為從服務(wù)器進(jìn)行相應(yīng)的身份驗證設(shè)置。
對于一個正在運(yùn)行的服務(wù)器, 可以使用客戶端輸入以下命令:
config set masterauth
要永久地設(shè)置這個密碼, 那么可以將它加入到配置文件中:
masterauth
詳細(xì)的信息可以參考 Redis 源碼中附帶的redis.conf 示例文件。
主服務(wù)器只在有至少 N 個從服務(wù)器的情況下,才執(zhí)行寫操作
從 Redis 2.8 開始, 為了保證數(shù)據(jù)的安全性, 可以通過配置, 讓主服務(wù)器只在有至少 N 個當(dāng)前已連接從服務(wù)器的情況下, 才執(zhí)行寫命令。不過, 因為 Redis 使用異步復(fù)制, 所以主服務(wù)器發(fā)送的寫數(shù)據(jù)并不一定會被從服務(wù)器接收到, 因此, 數(shù)據(jù)丟失的可能性仍然是存在的。以下是這個特性的運(yùn)作原理:
從服務(wù)器以每秒一次的頻率 PING 主服務(wù)器一次, 并報告復(fù)制流的處理情況。
主服務(wù)器會記錄各個從服務(wù)器最后一次向它發(fā)送 PING 的時間。
用戶可以通過配置, 指定網(wǎng)絡(luò)延遲的更大值 min-slaves-max-lag , 以及執(zhí)行寫操作所需的至少從服務(wù)器數(shù)量 min-slaves-to-write 。
如果至少有 min-slaves-to-write 個從服務(wù)器, 并且這些服務(wù)器的延遲值都少于 min-slaves-max-lag 秒, 那么主服務(wù)器就會執(zhí)行客戶端請求的寫操作。你可以將這個特性看作 CAP 理論中的 C 的條件放寬版本: 盡管不能保證寫操作的持久性, 但起碼丟失數(shù)據(jù)的窗口會被嚴(yán)格限制在指定的秒數(shù)中。
如果條件達(dá)不到 min-slaves-to-write 和 min-slaves-max-lag 所指定的條件, 那么寫操作就不會被執(zhí)行, 主服務(wù)器會向請求執(zhí)行寫操作的客戶端返回一個錯誤。
以下是這個特性的兩個選項和它們所需的參數(shù):
min-slaves-to-write
min-slaves-max-lag
詳細(xì)的信息可以參考 Redis 源碼中附帶的 redis.conf 示例文件。
Redis可擴(kuò)展集群搭建
1. 主動復(fù)制避開Redis復(fù)制缺陷。
既然Redis的復(fù)制功能有缺陷,不妨放棄Redis本身提供的復(fù)制功能,我們可以采用主動復(fù)制的方式來搭建我們的集群環(huán)境。所謂 主動復(fù)制 是指由業(yè)務(wù)端或者通過代理中間件對Redis存儲的數(shù)據(jù)進(jìn)行雙寫或多寫,通過數(shù)據(jù)的多份存儲來達(dá)到與復(fù)制相同的目的,主動復(fù)制不僅限于 用在Redis集群上,目前很多公司采用主動復(fù)制的技術(shù)來解決MySQL主從之間復(fù)制的延遲問題,比如Twitter還專門開發(fā)了用于復(fù)制和分區(qū)的中間件gizzard(
) 。
主動復(fù)制雖然解決了被動復(fù)制的延遲問題,但也帶來了新的問題,就是數(shù)據(jù)的一致性問題,數(shù)據(jù)寫2次或多次,如何保證多份數(shù)據(jù)的一致性呢?如果你的應(yīng)用 對數(shù)據(jù)一致性要求不高,允許最終一致性的話,那么通常簡單的解決方案是可以通過時間戳或者vector clock等方式,讓客戶端同時取到多份數(shù)據(jù)并進(jìn)行校驗,如果你的應(yīng)用對數(shù)據(jù)一致性要求非常高,那么就需要引入一些復(fù)雜的一致性算法比如Paxos來保證 數(shù)據(jù)的一致性,但是寫入性能也會相應(yīng)下降很多。
通過主動復(fù)制,數(shù)據(jù)多份存儲我們也就不再擔(dān)心Redis單點(diǎn)故障的問題了,如果一組Redis集群掛掉,我們可以讓業(yè)務(wù)快速切換到另一組Redis上,降低業(yè)務(wù)風(fēng)險。
2. 通過presharding進(jìn)行Redis在線擴(kuò)容。
通過主動復(fù)制我們解決了Redis單點(diǎn)故障問題,那么還有一個重要的問題需要解決:容量規(guī)劃與在線擴(kuò)容問題。我們前面分析過Redis的適用場景是全部數(shù)據(jù)存儲在內(nèi)存中,而內(nèi)存容量有限,那么首先需要根據(jù)業(yè)務(wù)數(shù)據(jù)量進(jìn)行初步的容量規(guī)劃,比如你的業(yè)務(wù)數(shù)據(jù)需 要100G存儲空間,假設(shè)服務(wù)器內(nèi)存是48G,至少需要3~4臺服務(wù)器來存儲。這個實(shí)際是對現(xiàn)有 業(yè)務(wù)情況所做的一個容量規(guī)劃,假如業(yè)務(wù)增長很快,很快就會發(fā)現(xiàn)當(dāng)前的容量已經(jīng)不夠了,Redis里面存儲的數(shù)據(jù)很快就會超過物理內(nèi)存大小,如何進(jìn)行 Redis的在線擴(kuò)容呢?Redis的作者提出了一種叫做presharding的方案來解決動態(tài)擴(kuò)容和數(shù)據(jù)分區(qū)的問題,實(shí)際就是在同一臺機(jī)器上部署多個Redis實(shí)例的方式,當(dāng)容量不夠時將多個實(shí)例拆分到不同的機(jī)器上,這樣實(shí)際就達(dá)到了擴(kuò)容的效果。
拆分過程如下:
在新機(jī)器上啟動好對應(yīng)端口的Redis實(shí)例。
配置新端口為待遷移端口的從庫。
待復(fù)制完成,與主庫完成同步后,切換所有客戶端配置到新的從庫的端口。
配置從庫為新的主庫。
移除老的端口實(shí)例。
重復(fù)上述過程遷移好所有的端口到指定服務(wù)器上。
以上拆分流程是Redis作者提出的一個平滑遷移的過程,不過該拆分方法還是很依賴Redis本身的復(fù)制功能的,如果主庫快照數(shù)據(jù)文件過大,這個復(fù)制的過程也會很久,同時會給主庫帶來壓力。所以做這個拆分的過程更好選擇為業(yè)務(wù)訪問低峰時段進(jìn)行。
新浪微博的replication改進(jìn)思路:
首先寫Redis的AOF文件,并對這個AOF文件按文件大小進(jìn)行自動分割滾動,同時關(guān)閉Redis的Rewrite命令,然后會在業(yè)務(wù)低峰時間進(jìn)行內(nèi)存快照存儲,并把當(dāng)前的AOF文件位置一起寫入到快照文件中,這樣我們可以使快照文件與AOF文件的位置保持一致性,這樣我們得到了系統(tǒng)某一時刻的內(nèi)存快照,并且同時也能知道這一時刻對應(yīng)的AOF文件的位置,那么當(dāng)從庫發(fā)送同步命令時,我們首先會把快照文件發(fā)送給從庫,然后從庫會取出該快照文件中存儲的AOF文件位置,并將該位置發(fā)給主庫,主庫會隨后發(fā)送該位置之后的所有命令,以后的復(fù)制就都是這個位置之后的增量信息了。
Redis的復(fù)制由于會使用快照持久化方式,所以如果Redis持久化方式選擇的是日志追加方式(aof),那么系統(tǒng)有可能在同一時刻既做aof日志文件的同步刷寫磁盤,又做快照寫磁盤操作,這個時候Redis的響應(yīng)能力會受到影響。所以如果選用aof持久化,則加從庫需要更加謹(jǐn)慎。
總結(jié)
Master更好不要做任何持久化工作,包括內(nèi)存快照和AOF日志文件,特別是不要啟用內(nèi)存快照做持久化。
如果數(shù)據(jù)比較關(guān)鍵,某個Slave開啟AOF備份數(shù)據(jù),策略為每秒同步一次。
為了主從復(fù)制的速度和連接的穩(wěn)定性,Slave和Master更好在同一個局域網(wǎng)內(nèi)。
盡量避免在壓力較大的主庫上增加從庫
為了Master的穩(wěn)定性,主從復(fù)制不要用圖狀結(jié)構(gòu),用單向鏈表結(jié)構(gòu)更穩(wěn)定,即主從關(guān)系為:Master
參考資料:
《redis設(shè)計與實(shí)現(xiàn)》
狹義上的有機(jī)化合物主要是由碳元素、氫元素組成,是一定含碳的化合物,但是不包括碳的氧化返尺物(一氧化碳、二氧化碳)、碳酸,碳酸鹽配世搏、氰化物、硫氰化物、培祥氰酸鹽、金屬碳化物、部分簡單含碳化合物(如SiC)等物質(zhì)。但廣義有機(jī)化合物可以不含碳元素。
關(guān)于異步更新redis的數(shù)據(jù)庫的介紹到此就結(jié)束了,不知道你從中找到你需要的信息了嗎 ?如果你還想了解更多這方面的信息,記得收藏關(guān)注本站。
成都網(wǎng)站建設(shè)選創(chuàng)新互聯(lián)(?:028-86922220),專業(yè)從事成都網(wǎng)站制作設(shè)計,高端小程序APP定制開發(fā),成都網(wǎng)絡(luò)營銷推廣等一站式服務(wù)。
分享名稱:高效實(shí)現(xiàn)數(shù)據(jù)更新:異步處理Redis數(shù)據(jù)庫(異步更新redis的數(shù)據(jù)庫)
當(dāng)前網(wǎng)址:http://m.5511xx.com/article/djgegii.html


咨詢
建站咨詢
