国产av一二三区|日本不卡动作网站|黄色天天久久影片|99草成人免费在线视频|AV三级片成人电影在线|成年人aV不卡免费播放|日韩无码成人一级片视频|人人看人人玩开心色AV|人妻系列在线观看|亚洲av无码一区二区三区在线播放

網(wǎng)易首頁(yè) > 網(wǎng)易號(hào) > 正文 申請(qǐng)入駐

Meta如何用極致技術(shù)實(shí)現(xiàn)接近完美的緩存一致性?

0
分享至

點(diǎn)擊下方“JavaEdge”,選擇“設(shè)為星標(biāo)”

第一時(shí)間關(guān)注技術(shù)干貨!


免責(zé)聲明~ 任何文章不要過度深思! 萬(wàn)事萬(wàn)物都經(jīng)不起審視,因?yàn)槭郎蠜]有同樣的成長(zhǎng)環(huán)境,也沒有同樣的認(rèn)知水平,更「沒有適用于所有人的解決方案」; 不要急著評(píng)判文章列出的觀點(diǎn),只需代入其中,適度審視一番自己即可,能「跳脫出來從外人的角度看看現(xiàn)在的自己處在什么樣的階段」才不為俗人。 怎么想、怎么做,全在乎自己「不斷實(shí)踐中尋找適合自己的大道」

0 導(dǎo)言

緩存是一種強(qiáng)大的技術(shù),廣泛應(yīng)用于計(jì)算機(jī)系統(tǒng)的各個(gè)方面,從緩存等硬件到操作系統(tǒng)、網(wǎng)絡(luò)瀏覽器,尤其是后端開發(fā)。對(duì)于 Meta 這樣的公司來說,緩存是非常重要的,因?yàn)樗梢詭椭麄儨p少延遲、擴(kuò)展繁重的工作負(fù)載并節(jié)省資金。由于他們的用例非常依賴緩存,這就給他們帶來了另一系列問題,那就是緩存失效。

多年來,Meta 已將緩存一致性從 99.9999(6 個(gè) 9)提高到 99.99999999(10 個(gè) 9),即其緩存集群中,100 億次緩存寫入中只有不到 1 次不一致。本文討論:

  1. 什么是緩存失效和緩存一致性?

  2. Meta 為何如此重視緩存一致性,以至于連六個(gè)九都不夠?

  3. Meta 的監(jiān)控系統(tǒng)如何幫助他們改進(jìn)緩存失效、緩存一致性并修復(fù)錯(cuò)誤

1 緩存失效和緩存一致性

顧名思義,緩存并不保存數(shù)據(jù)真實(shí)來源,因此當(dāng)真實(shí)來源中的數(shù)據(jù)發(fā)生變化時(shí),應(yīng)該有一個(gè)主動(dòng)失效陳舊緩存條目的過程。若失效過程處理不當(dāng),會(huì)在緩存中無限期地留下與真實(shí)源中不同的不一致值。

咋才能使緩存失效呢?

可設(shè)置一個(gè) TTL 保持緩存的新鮮度,就不會(huì)有來自其他系統(tǒng)的緩存失效。但本文討論mata的緩存一致性問題,我們將假設(shè)無效操作是由緩存本身以外的其他系統(tǒng)執(zhí)行的。

先看咋引入緩存不一致:

假設(shè) 1、2、3、4 依次遞增的時(shí)間戳

  1. 緩存先嘗試從數(shù)據(jù)庫(kù)中填充值

  2. 但 x=42 的值到達(dá)緩存前,一些操作更新了數(shù)據(jù)庫(kù)中 x=43 的值

  3. 數(shù)據(jù)庫(kù)為 x=43 發(fā)送緩存失效事件,該事件在 x=42 之前到達(dá)緩存,緩存值被設(shè)置為 43

  4. 事件 x =42 現(xiàn)在到達(dá)緩存,緩存被設(shè)置為 42,于是出現(xiàn)不一致

為解決此問題,可用version字段來執(zhí)行沖突解決,舊版本就不會(huì)覆蓋新版本。這種解決方案適用互聯(lián)網(wǎng) 99% 的公司,但由于其系統(tǒng)復(fù)雜性,即使這樣的解決方案也可能無法滿足 Meta 的運(yùn)營(yíng)規(guī)模。

2 為啥Meta如此關(guān)注緩存一致性?

  • 從Meta的角度,緩存不一致幾乎與數(shù)據(jù)庫(kù)數(shù)據(jù)丟失一樣糟糕

  • 而從用戶角度,緩存不一致可能導(dǎo)致非常糟糕的用戶體驗(yàn)

當(dāng)你在 Ins 上向用戶發(fā)送 DM 時(shí),在幕后會(huì)有一個(gè)用戶到主存儲(chǔ)的映射,用戶的信息就存儲(chǔ)在主存儲(chǔ)中。 想象有三個(gè)用戶。鮑勃、瑪麗和愛麗絲。兩個(gè)用戶都向 Alice 發(fā)送一條信息。鮑勃在美國(guó),愛麗絲在歐洲,瑪麗在日本。因此,系統(tǒng)會(huì)查詢離用戶居住地最近的地區(qū),從而將信息發(fā)送到 Alice 數(shù)據(jù)存儲(chǔ)區(qū)。在這種情況下,當(dāng) TAO 復(fù)制品查詢 BOB 和 Mary 居住的地區(qū)時(shí),它們都有不一致的數(shù)據(jù),因此它將消息發(fā)送到了沒有 Alice 消息的地區(qū)。

上述情況下,會(huì)出現(xiàn)信息丟失和糟糕的用戶體驗(yàn),因此這是 meta 要解決的首要問題之一。

3 監(jiān)測(cè)

要解決緩存失效和緩存一致性問題,先測(cè)量。如能精確測(cè)量緩存一致性,并在緩存出現(xiàn)不一致記錄時(shí)發(fā)出警報(bào),Meta 就能確保他們的測(cè)量結(jié)果不包含任何誤報(bào),因?yàn)橹蛋喙こ處煏?huì)學(xué)會(huì)忽略它,這樣該指標(biāo)就會(huì)失去信任,變得毫無用處。

深入探討 Meta 解決方案前,最簡(jiǎn)單的解決方案就是記錄和跟蹤每次緩存狀態(tài)的變化。工作負(fù)載小時(shí),該方案可行,但 Meta 系統(tǒng)每天的緩存填充量超過 10 萬(wàn)億次。記錄和跟蹤所有的緩存狀態(tài)會(huì)將一個(gè)準(zhǔn)備就緒的緩存工作負(fù)載變成一個(gè)極其繁重的工作負(fù)載,甚至都不用考慮咋調(diào)試。

4 Polaris

Polaris 在很高的層次上以客戶身份與有狀態(tài)服務(wù)交互,并且不假定對(duì)服務(wù)內(nèi)部結(jié)構(gòu)有任何了解。Polaris 工作原則:緩存最終應(yīng)與數(shù)據(jù)庫(kù)保持一致。Polaris 收到無效事件后會(huì)查詢所有副本,以驗(yàn)證是否發(fā)生其他違規(guī)事件。如 Polaris 接收到 x=4 版本 4 的無效事件,它就會(huì)以客戶端身份檢查所有緩存副本,以驗(yàn)證是否有任何違反不變式的情況發(fā)生。若某副本返回 x=3 @ 版本 3,Polaris 就會(huì)將其標(biāo)記為不一致,并重新獲取樣本,隨后再針對(duì)同一目標(biāo)緩存主機(jī)進(jìn)行檢查。Polaris 會(huì)以特定的時(shí)間尺度(如一分鐘、五分鐘或十分鐘)報(bào)告不一致情況。

這種多時(shí)間尺度的設(shè)計(jì)不僅使 Polaris 能夠在內(nèi)部擁有多個(gè)隊(duì)列,從而高效地實(shí)施后退和重試,而且對(duì)于防止產(chǎn)生誤報(bào)也至關(guān)重要。

4.1 舉例

假設(shè) Polaris 接收到一個(gè)version=4 的無效信息 x = 4。但當(dāng) Polaris 檢查緩存時(shí),卻找不到 x 的條目,因此應(yīng)將其標(biāo)記為不一致。此時(shí),有兩種可能:

  1. x 在版本 3 不可見,但版本 4 的寫入是對(duì)Key的最新寫入,這確實(shí)是緩存不一致

  2. 可能版本 5 的寫入刪除了鍵 x,也許 Polaris 只是看到了比失效事件中的數(shù)據(jù)更新的數(shù)據(jù)視圖

哪種正確?

為驗(yàn)證,Polaris 需查詢數(shù)據(jù)庫(kù)。繞過緩存的查詢可能是計(jì)算密集型的,也可能使數(shù)據(jù)庫(kù)面臨風(fēng)險(xiǎn),因?yàn)楸Wo(hù)數(shù)據(jù)庫(kù)和擴(kuò)展讀取重型工作負(fù)載是緩存最常見的兩種使用情況。因此,不能向系統(tǒng)發(fā)送過多查詢。

Polaris 解決方案是延遲執(zhí)行此類檢查,并調(diào)用數(shù)據(jù)庫(kù),直到不一致樣本跨過設(shè)定的閾值(如 1min或 5 min)。Polaris 產(chǎn)品的指標(biāo)是 "在 M 分鐘內(nèi)九分之九的 cahce 寫入是一致的"。因此,現(xiàn)在 Polaris 提供的指標(biāo)是:在 5 分鐘的時(shí)間范圍內(nèi),99.99999999 次緩存是一致的。

編碼示例

一個(gè)咋產(chǎn)生緩存不一致的編碼示例,看 polaris 咋幫 Meta 解決的一個(gè) bug。設(shè)有一高速緩存,維護(hù)著K到Meta數(shù)據(jù)的映射和K到version的映射:

cache_data = {}
cache_version = {}
meta_data_table = {"1": 42}
version_table = {"1": 4}

  1. 當(dāng)讀請(qǐng)求到來,先檢查緩存值,如緩存中無該值,則從數(shù)據(jù)庫(kù)返回該值:


def read_value(key):
value = read_value_from_cache(key)
if value is not None:
return value
else:
return meta_data_table[key]


def read_value_from_cache(key):
if key in cache_data:
return cache_data[key]
else:
fill_cache_thread = threading.Thread(target=fill_cache(key))
fill_cache_thread.start()
return None

2.緩存返回 None 結(jié)果,然后開始從數(shù)據(jù)庫(kù)填充緩存。我在這里使用了線程來使進(jìn)程異步。

def fill_cache_metadata(key):
meta_data = meta_data_table[key]
print("Filling cache meta data for", meta_data)
cache_data[key] = meta_data

def fill_cache_version(key):
time.sleep(2)
version = version_table[key]
print("Filling cache version data for", version)
cache_version[key] = version

def write_value(key, value):
version = 1
if key in version_table:
version = version_table[key]
version = version + 1

write_in_databse_transactionally(key, value, version)
time.sleep(3)
invalidate_cache(key, value, version)

def write_in_databse_transactionally(key, data, version):
meta_data_table[key] = data
version_table[key] = version

3.與此同時(shí),當(dāng)版本數(shù)據(jù)被填入緩存時(shí),數(shù)據(jù)庫(kù)會(huì)有新的寫入請(qǐng)求來更新元數(shù)據(jù)值和版本值。此時(shí)此刻,這看起來像是一個(gè)錯(cuò)誤,但其實(shí)不是,因?yàn)榫彺媸?yīng)使緩存恢復(fù)到與數(shù)據(jù)庫(kù)一致的狀態(tài)(在緩存中添加了 time.sleep,并在數(shù)據(jù)庫(kù)中添加了寫入函數(shù),以重現(xiàn)該問題)。

def invalidate_cache(key, metadata, version):
try:
cache_data = cache_data[key][value] ## To produce error
except:
drop_cache(key, version)

def drop_cache(key, version):
cache_version_value = cache_version[key]
if version > cache_version_value:
cache_data.pop(key)
cache_version.pop(key)

  1. 之后,在緩存失效過程中,由于某些原因?qū)е率。谶@種情況下,異常處理程序有條件放棄緩存。

    刪除緩存函數(shù)的邏輯是,如果最新值大于 cache_version_value,則刪除該鍵,但在我們的情況下并非如此。因此,這會(huì)導(dǎo)致在緩存中無限期地保留陳舊的元數(shù)據(jù)

記住,這只是錯(cuò)誤可能發(fā)生的非常簡(jiǎn)單的變體,實(shí)際的錯(cuò)誤更加錯(cuò)綜復(fù)雜,涉及到數(shù)據(jù)庫(kù)復(fù)制和跨區(qū)域通信。只有當(dāng)上述所有步驟都按此順序發(fā)生時(shí),才會(huì)觸發(fā)錯(cuò)誤。不一致性很少被觸發(fā)。錯(cuò)誤隱藏在交錯(cuò)操作和瞬時(shí)錯(cuò)誤后面的錯(cuò)誤處理代碼中。

5 一致性跟蹤

既然你已接到 Polaris 緩存不一致的呼喚,最重要的就是檢查日志,看問題在哪。正如之前所討論,記錄每個(gè)緩存數(shù)據(jù)變化幾乎不可能,但若只記錄有可能導(dǎo)致變化的變化呢?

若看到上面代碼,那么如果緩存沒有收到失效事件或失效沒有起作用,就會(huì)出現(xiàn)問題。從 oncall 角度,需檢查:

  • 緩存服務(wù)器是否收到了無效信息?

  • 服務(wù)器是否正確處理了失效?

  • 之后該條目是否變得不一致?

Meta 構(gòu)建了一個(gè)有狀態(tài)跟蹤庫(kù),可記錄和跟蹤紫色小窗口中的緩存突變,所有有趣而復(fù)雜的交互都會(huì)觸發(fā)錯(cuò)誤,導(dǎo)致緩存不一致。

6 結(jié)論

對(duì)任何分布式系統(tǒng),可靠的監(jiān)控和日志系統(tǒng)必不可少,才能確保我們抓住漏洞,并在抓住漏洞后迅速找到根本原因,減少問題。以 Meta 為例,Polaris 發(fā)現(xiàn)異常后立即發(fā)出警報(bào)。利用一致性跟蹤的信息,值班工程師只用了不到 30 分鐘就找到了錯(cuò)誤所在。

參考:

  • https://engineering.fb.com/2022/06/08/core-infra/cache-made-consistent/

  • 在這里找到我創(chuàng)建錯(cuò)誤的實(shí)現(xiàn)方法: https://github.com/Mayank-Sharma-27/meta-cache-made-consistent

  • Linkedin: https://www.linkedin.com/in/mayank-sharma-2002bb10b/

關(guān)注我,緊跟本系列專欄文章,咱們下篇再續(xù)!

★ 作者簡(jiǎn)介:魔都架構(gòu)師,多家大廠后端一線研發(fā)經(jīng)驗(yàn),在分布式系統(tǒng)設(shè)計(jì)、數(shù)據(jù)平臺(tái)架構(gòu)和AI應(yīng)用開發(fā)等領(lǐng)域都有豐富實(shí)踐經(jīng)驗(yàn)。 各大技術(shù)社區(qū)頭部專家博主。具有豐富的引領(lǐng)團(tuán)隊(duì)經(jīng)驗(yàn),深厚業(yè)務(wù)架構(gòu)和解決方案的積累。 負(fù)責(zé): 中央/分銷預(yù)訂系統(tǒng)性能優(yōu)化 活動(dòng)&券等營(yíng)銷中臺(tái)建設(shè) 交易平臺(tái)及數(shù)據(jù)中臺(tái)等架構(gòu)和開發(fā)設(shè)計(jì) 車聯(lián)網(wǎng)核心平臺(tái)-物聯(lián)網(wǎng)連接平臺(tái)、大數(shù)據(jù)平臺(tái)架構(gòu)設(shè)計(jì)及優(yōu)化 LLM Agent應(yīng)用開發(fā) 區(qū)塊鏈應(yīng)用開發(fā) 大數(shù)據(jù)開發(fā)挖掘經(jīng)驗(yàn) 推薦系統(tǒng)項(xiàng)目 目前主攻市級(jí)軟件項(xiàng)目設(shè)計(jì)、構(gòu)建服務(wù)全社會(huì)的應(yīng)用系統(tǒng)。 ”

參考:

  • 編程嚴(yán)選網(wǎng)

編程嚴(yán)選網(wǎng):http://www.javaedge.cn/ 專注分享軟件開發(fā)全生態(tài)相關(guān)技術(shù)文章、視頻教程資源、熱點(diǎn)資訊等,全站資源免費(fèi)學(xué)習(xí),快來看看吧~ 【編程嚴(yán)選】星球

歡迎長(zhǎng)按圖片加好友,我會(huì)第一時(shí)間和你分享軟件行業(yè)趨勢(shì),面試資源,學(xué)習(xí)方法等等。

添加好友備注【技術(shù)群交流】拉你進(jìn)技術(shù)交流群

關(guān)注公眾號(hào)后,在后臺(tái)私信:

  • 更多教程資源應(yīng)有盡有,歡迎關(guān)注并加技術(shù)交流群,慢慢獲取

  • 為避免大量資源被收藏白嫖而浪費(fèi)各自精力,以上資源領(lǐng)取分別需要收取1元門檻費(fèi)!


特別聲明:以上內(nèi)容(如有圖片或視頻亦包括在內(nèi))為自媒體平臺(tái)“網(wǎng)易號(hào)”用戶上傳并發(fā)布,本平臺(tái)僅提供信息存儲(chǔ)服務(wù)。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相關(guān)推薦
熱點(diǎn)推薦
賈玲為張小斐慶生!本人沒復(fù)胖目測(cè)100斤,私下沒架子超級(jí)好相處

賈玲為張小斐慶生!本人沒復(fù)胖目測(cè)100斤,私下沒架子超級(jí)好相處

章眽八卦
2026-01-11 13:23:59
相聲演員笑林:不抽煙,不喝酒,一天100個(gè)俯臥撐,59歲驟然離世

相聲演員笑林:不抽煙,不喝酒,一天100個(gè)俯臥撐,59歲驟然離世

林雁飛
2026-01-10 15:24:20
44歲秦嵐同居實(shí)錘!情侶拖鞋+見家長(zhǎng),偏不領(lǐng)證太清醒

44歲秦嵐同居實(shí)錘!情侶拖鞋+見家長(zhǎng),偏不領(lǐng)證太清醒

陳意小可愛
2026-01-09 08:29:47
突發(fā)!山東一地120調(diào)度員集中離職!4人已離職、2人提出辭職……

突發(fā)!山東一地120調(diào)度員集中離職!4人已離職、2人提出辭職……

醫(yī)脈圈
2026-01-11 12:16:08
零度的上海夜晚,女孩街頭跪地行走,母親竟在一旁監(jiān)督……多方已介入

零度的上海夜晚,女孩街頭跪地行走,母親竟在一旁監(jiān)督……多方已介入

環(huán)球網(wǎng)資訊
2026-01-11 20:05:43
滇池旁14車一夜變廢鐵!重慶游客返程前心碎,以后再也不來了!

滇池旁14車一夜變廢鐵!重慶游客返程前心碎,以后再也不來了!

游者走天下
2026-01-09 10:55:20
地鐵直達(dá)!上海又一座巨無霸商場(chǎng)!6500㎡星空露臺(tái)+10000㎡中央公園

地鐵直達(dá)!上海又一座巨無霸商場(chǎng)!6500㎡星空露臺(tái)+10000㎡中央公園

上觀新聞
2026-01-11 14:24:24
閆學(xué)晶多平臺(tái)賬號(hào)被禁止關(guān)注,馮鞏刪除所有相關(guān)視頻

閆學(xué)晶多平臺(tái)賬號(hào)被禁止關(guān)注,馮鞏刪除所有相關(guān)視頻

映射生活的身影
2026-01-10 10:38:36
考官問“什么門永遠(yuǎn)關(guān)不上”在場(chǎng)考生答錯(cuò),7歲小朋友出正確答案

考官問“什么門永遠(yuǎn)關(guān)不上”在場(chǎng)考生答錯(cuò),7歲小朋友出正確答案

蘭姐說故事
2026-01-09 20:05:03
決議生效!芬蘭正式“退群”

決議生效!芬蘭正式“退群”

環(huán)球時(shí)報(bào)國(guó)際
2026-01-10 22:57:42
中美合作 斬殺日本

中美合作 斬殺日本

云石
2026-01-11 11:33:01
明搶5000萬(wàn)桶石油后,特朗普轉(zhuǎn)頭才發(fā)現(xiàn):中國(guó)連一桶都不肯買了?

明搶5000萬(wàn)桶石油后,特朗普轉(zhuǎn)頭才發(fā)現(xiàn):中國(guó)連一桶都不肯買了?

書紀(jì)文譚
2026-01-11 19:36:13
越南不恨美國(guó),不恨日本,連殖民幾十年的法國(guó)都不恨,就只恨中國(guó)

越南不恨美國(guó),不恨日本,連殖民幾十年的法國(guó)都不恨,就只恨中國(guó)

我心縱橫天地間
2026-01-07 19:17:18
中東國(guó)家都意識(shí)到了:就算中國(guó)高端武器再多,也沒辦法保護(hù)他們

中東國(guó)家都意識(shí)到了:就算中國(guó)高端武器再多,也沒辦法保護(hù)他們

肖茲探秘說
2026-01-01 20:16:34
年內(nèi)跌的最慘股票之一,跌了10個(gè)月,從28跌到5塊,這還怎么玩!

年內(nèi)跌的最慘股票之一,跌了10個(gè)月,從28跌到5塊,這還怎么玩!

財(cái)經(jīng)市界
2026-01-11 17:26:52
俄羅斯榛樹導(dǎo)彈故意不裝彈頭,烏方承認(rèn):雷達(dá)完全失效,看不見

俄羅斯榛樹導(dǎo)彈故意不裝彈頭,烏方承認(rèn):雷達(dá)完全失效,看不見

科普100克克
2026-01-11 11:44:23
科學(xué)家讓一對(duì)情侶在核磁共振里實(shí)戰(zhàn),才發(fā)現(xiàn)人體驚人真相!

科學(xué)家讓一對(duì)情侶在核磁共振里實(shí)戰(zhàn),才發(fā)現(xiàn)人體驚人真相!

徐德文科學(xué)頻道
2026-01-06 19:51:55
國(guó)乒四大主力全傷了!男隊(duì)無人可用全軍覆沒,王皓爭(zhēng)議舉動(dòng)太落魄

國(guó)乒四大主力全傷了!男隊(duì)無人可用全軍覆沒,王皓爭(zhēng)議舉動(dòng)太落魄

三十年萊斯特城球迷
2026-01-11 20:39:33
官媒發(fā)文,揭開王思聰與秦嵐真實(shí)關(guān)系,原來汪小菲一個(gè)字都沒說錯(cuò)

官媒發(fā)文,揭開王思聰與秦嵐真實(shí)關(guān)系,原來汪小菲一個(gè)字都沒說錯(cuò)

郭蛹包工頭
2026-01-08 18:19:09
歐媒:中國(guó)都上桌了,500年來頭一次,瓜分世界怎能沒有歐洲的份

歐媒:中國(guó)都上桌了,500年來頭一次,瓜分世界怎能沒有歐洲的份

阿器談史
2025-12-25 21:09:35
2026-01-11 21:16:49
JavaEdge incentive-icons
JavaEdge
Java 技術(shù)
466文章數(shù) 457關(guān)注度
往期回顧 全部

科技要聞

“我們與美國(guó)的差距也許還在拉大”

頭條要聞

零度天母親罰女兒在街頭跪地行走 還對(duì)勸阻者出言不遜

頭條要聞

零度天母親罰女兒在街頭跪地行走 還對(duì)勸阻者出言不遜

體育要聞

詹皇曬照不滿打手沒哨 裁判報(bào)告最后兩分鐘無誤判

娛樂要聞

留幾手為閆學(xué)晶叫屈?稱網(wǎng)友自卑敏感

財(cái)經(jīng)要聞

外賣平臺(tái)"燒錢搶存量市場(chǎng)"迎來終局?

汽車要聞

2026款宋Pro DM-i長(zhǎng)續(xù)航補(bǔ)貼后9.98萬(wàn)起

態(tài)度原創(chuàng)

房產(chǎn)
家居
手機(jī)
數(shù)碼
公開課

房產(chǎn)要聞

66萬(wàn)方!4755套!三亞巨量房源正瘋狂砸出!

家居要聞

木色留白 演繹現(xiàn)代自由

手機(jī)要聞

華為Pura 90系列再次被確認(rèn):首發(fā)HarmonyOS 6.1,獨(dú)占無損長(zhǎng)焦!

數(shù)碼要聞

ECS精英推出Liva Z系列迷你主機(jī),多CPU可選

公開課

李玫瑾:為什么性格比能力更重要?

無障礙瀏覽 進(jìn)入關(guān)懷版