日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 运维知识 > 数据库 >内容正文

数据库

阿里云数据库开源发布:PolarDB HTAP的功能特性和关键技术

發(fā)布時(shí)間:2024/8/23 数据库 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 阿里云数据库开源发布:PolarDB HTAP的功能特性和关键技术 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

簡(jiǎn)介:在3月2日的阿里云開(kāi)源 PolarDB 企業(yè)級(jí)架構(gòu)發(fā)布會(huì)上,阿里云 PolarDB 內(nèi)核技術(shù)專家嚴(yán)華帶來(lái)了主題為《PolarDB HTAP詳解》的精彩演講。在PolarDB存儲(chǔ)計(jì)算分離架構(gòu)的基礎(chǔ)上,我們研發(fā)了基于共享存儲(chǔ)的MPP分布式執(zhí)行引擎,解決了單條SQL執(zhí)行時(shí)無(wú)法利用其它節(jié)點(diǎn)計(jì)算資源、無(wú)法發(fā)揮共享存儲(chǔ)池的IO大帶寬的問(wèn)題,同時(shí)提供了彈性計(jì)算,彈性擴(kuò)展的保障,使得PolarDB初步具備了 HTAP 的能力。本議題主要介紹PolarDB HTAP的功能特性和關(guān)鍵技術(shù)。

在3月2日的阿里云開(kāi)源 PolarDB 企業(yè)級(jí)架構(gòu)發(fā)布會(huì)上,阿里云 PolarDB 內(nèi)核技術(shù)專家嚴(yán)華帶來(lái)了主題為《PolarDB HTAP詳解》的精彩演講。在PolarDB存儲(chǔ)計(jì)算分離架構(gòu)的基礎(chǔ)上,我們研發(fā)了基于共享存儲(chǔ)的MPP分布式執(zhí)行引擎,解決了單條SQL執(zhí)行時(shí)無(wú)法利用其它節(jié)點(diǎn)計(jì)算資源、無(wú)法發(fā)揮共享存儲(chǔ)池的IO大帶寬的問(wèn)題,同時(shí)提供了彈性計(jì)算,彈性擴(kuò)展的保障,使得PolarDB初步具備了 HTAP 的能力。本議題主要介紹PolarDB HTAP的功能特性和關(guān)鍵技術(shù)。

直播回顧視頻:開(kāi)源PolarDB企業(yè)級(jí)架構(gòu)重磅發(fā)布-阿里云
PDF下載:?文件下載-阿里云開(kāi)發(fā)者社區(qū)

以下根據(jù)發(fā)布會(huì)演講視頻內(nèi)容整理:

一、背景

很多PolarDB 的用戶都有 TP 和 AP 共用的需求,他們白天使用 PolarDB處理高并發(fā)的 TP 請(qǐng)求,晚上 TP 流量下降、機(jī)器空閑后繼續(xù)使用 PolarDB 進(jìn)行 AP 的報(bào)表分析。但是,即使這樣,依然沒(méi)有最大化利用空閑機(jī)器資源。

因?yàn)樵?PolarDB PG 系統(tǒng)在處理復(fù)雜的 AP 查詢時(shí)會(huì)遇到兩大挑戰(zhàn):首先,單個(gè) SQL 在原生 PG 執(zhí)行引擎下只能在單個(gè)節(jié)點(diǎn)上執(zhí)行,無(wú)論是單機(jī)串行還是單機(jī)并行,都無(wú)法利用其他節(jié)點(diǎn)的 CPU memory 等計(jì)算資源,只能縱向 Scale Up,不能橫向 Scale Out ;其次,PolarDB 底層是存儲(chǔ)池,理論上 IO 吞吐是無(wú)限大的。而單個(gè) SQL 在原生 PG 執(zhí)行引擎下只能在單個(gè)節(jié)點(diǎn)上執(zhí)行,受限于單個(gè)節(jié)點(diǎn)的 CPU 和 memory 的瓶頸,無(wú)法充分發(fā)揮存儲(chǔ)側(cè)大 IO 帶寬的優(yōu)勢(shì)。

為了解決用戶實(shí)際使用中的痛點(diǎn),PolarDB 決定做 HTAP。 當(dāng)前業(yè)界HTAP的解決方案主要有以下三種:

① TP 和 AP 在存儲(chǔ)計(jì)算上都分離,能夠?qū)崿F(xiàn)TP和AP完全隔離,互不影響。但實(shí)際使用中會(huì)存在一些問(wèn)題。首先,TP的數(shù)據(jù)需要導(dǎo)入到AP系統(tǒng)中,會(huì)存在一定的延遲,導(dǎo)致時(shí)效性不高;其次需要增加冗余的 AP 系統(tǒng),總成本也會(huì)增加;第三,增加了一套 AP 系統(tǒng)后,運(yùn)維難度也會(huì)增加。

② TP 和 AP 在存儲(chǔ)計(jì)算上都共享,這樣可以做到成本最小化,資源利用最大化,但仍然存在兩點(diǎn)問(wèn)題。首先,由于計(jì)算共享, AP 查詢和 TP 查詢同時(shí)運(yùn)行時(shí)或多或少會(huì)存在相互影響;其次,當(dāng) AP 查詢比重增大時(shí),系統(tǒng)需要擴(kuò)計(jì)算節(jié)點(diǎn)存儲(chǔ),因此需要重分布,導(dǎo)致無(wú)法快速?gòu)椥許cale Out。

③ TP 和 AP 在存儲(chǔ)上共享,在計(jì)算上分離。PolarDB 是存儲(chǔ)計(jì)算分離架構(gòu),因此天然支持此方案。

二、原理

基于 PolarDB 存儲(chǔ)計(jì)算分離的架構(gòu)。我們研發(fā)了分布式 MPP 執(zhí)行引擎,提供了跨機(jī)并行執(zhí)行、彈性計(jì)算彈性擴(kuò)展的保證,使得 PolarDB 初步具備了 HTAP 的能力。

上圖右是 PolarDB HTAP 的架構(gòu)圖。底層是池化了的共享存儲(chǔ),TP 和 AP 共享一套存儲(chǔ)數(shù)據(jù),在降低成本的同時(shí)能提供毫秒級(jí)的數(shù)據(jù)新鮮度,還提供了快速擴(kuò)容計(jì)算節(jié)點(diǎn)的能力,這也是 PolarDB HTAP 第一個(gè)特性。

上層是讀寫(xiě)分離的計(jì)算節(jié)點(diǎn)。PolarDB 具備兩套執(zhí)行引擎來(lái)處理 HTAP 查詢,其中單機(jī)執(zhí)行引擎在讀寫(xiě)節(jié)點(diǎn)上進(jìn)行處理高并發(fā)的 TP 查詢,分布式 MPP 執(zhí)行引擎在只讀節(jié)點(diǎn)上處理復(fù)雜的 AP 查詢,TP和 AP 的查詢天然進(jìn)行了物理隔離,解耦了 TP 和 AP 的計(jì)算環(huán)境,杜絕了 CPU 和 memory 的相互影響,這是 PolarDB HTAP 的第二大特性:TP/AP物理隔離 。

PolarDB HTAP 的第三大特性是 Serverless 彈性擴(kuò)展,消除了傳統(tǒng) MPP 數(shù)據(jù)庫(kù) coordinate 的單點(diǎn)限制,可以在任何一個(gè)只讀節(jié)點(diǎn)上發(fā)起 MPP,可以彈性調(diào)整 MPP 節(jié)點(diǎn)范圍以及單機(jī)并行度,同時(shí)支持 Scale Out、Scale Up 。此處的彈性調(diào)整是及時(shí)生效的,并不需要進(jìn)行數(shù)據(jù)重分布。

消除傾斜是 PolarDB HTAP 的第四大特性。PolarDB HTAP 在充分考慮 PG BufferPool 親和性的基礎(chǔ)上,能夠消除數(shù)據(jù)傾斜和計(jì)算傾斜,實(shí)現(xiàn)能者多勞的調(diào)度。

PolarDB HTAP 原理的核心是分布式 MPP 執(zhí)行引擎,它是典型的火山引擎。 AB 兩張表先做 join 再做聚合輸出,這也是 PG 單機(jī)執(zhí)行引擎的執(zhí)行流程。

在傳統(tǒng)的 MPP 執(zhí)行引擎中,數(shù)據(jù)被打散到不同的節(jié)點(diǎn)上,不同節(jié)點(diǎn)上的數(shù)據(jù)可能具有不同的分布屬性,比如哈希分布、隨機(jī)分布、復(fù)制表分布等。傳統(tǒng)的 MPP 執(zhí)行引擎會(huì)針對(duì)不同表的數(shù)據(jù)分布特點(diǎn),在計(jì)劃中插入算子來(lái)保證上層算子對(duì)數(shù)據(jù)的分布特征無(wú)感知。

PolarDB 是共享存儲(chǔ)架構(gòu),底層共享的數(shù)據(jù)可以被各個(gè)計(jì)算節(jié)點(diǎn)全量訪問(wèn)。如果使用傳統(tǒng)的 MPP 執(zhí)行引擎,每個(gè) Worker 都會(huì)掃描全量數(shù)據(jù),會(huì)產(chǎn)生重復(fù)的數(shù)據(jù),同時(shí)也沒(méi)有起到掃描時(shí)分治加速的效果,并不算真正意義上的 MPP 引擎。

因此,在在 PolarDB 分布式 MPP 執(zhí)行引擎中,我們借鑒了火山模型論文的思想,對(duì)所有掃描算子進(jìn)行并發(fā)處理,引入了PxScan算子來(lái)屏蔽共享存儲(chǔ)。PxScan算子將 share-storage 的數(shù)據(jù)映射為 share-nothing 的數(shù)據(jù),通過(guò) Worker之間的協(xié)調(diào),將目標(biāo)表劃分為多個(gè)虛擬分區(qū)數(shù)據(jù)塊,每個(gè) Worker 掃描各自虛擬分區(qū)數(shù)據(jù)塊,從而實(shí)現(xiàn)了跨機(jī)分布式并行scan。

PxScan算子掃描出來(lái)的數(shù)據(jù)會(huì)通過(guò) shuffle 算子來(lái)重分布,再在每個(gè) Worker 上如同執(zhí)行單機(jī)一樣,按照火山模型來(lái)執(zhí)行。

以上就是PolarDB 分布式 MPP 執(zhí)行引擎的核心:shuffle 算子屏蔽數(shù)據(jù)分布,PxScan 算子屏蔽共享存儲(chǔ)。

傳統(tǒng) MPP 只能在指定節(jié)點(diǎn)發(fā)起 MPP 查詢,因此每個(gè)節(jié)點(diǎn)上都只能有單個(gè) Worker 掃描一張表。為了支持云原生下 serverless彈性擴(kuò)展的需求,我們引入了分布式事務(wù)一致性保證。

首先,任意選擇一個(gè)節(jié)點(diǎn)作為 coordinator節(jié)點(diǎn),它的 ReadLSN 會(huì)作為約定的 LSN,從所有 MPP 節(jié)點(diǎn)的快照版本號(hào)中選擇最小的版本號(hào)作為全局約定的快照版本號(hào)。通過(guò) LSN 的等待回放和 Global Snaphot 同步機(jī)制,確保在任何一個(gè)節(jié)點(diǎn)發(fā)起 MPP 查詢時(shí),數(shù)據(jù)和快照均能達(dá)到一致可用的狀態(tài)。

為了達(dá)到 serverless 的彈性擴(kuò)展,我們還基于共享存儲(chǔ)的特點(diǎn),將 coordinator節(jié)點(diǎn)全鏈路上各個(gè)模塊需要的外部依賴都放至共享存儲(chǔ)上。各個(gè) Worker 節(jié)點(diǎn)運(yùn)行時(shí)需要的參數(shù)也會(huì)通過(guò)控制鏈路從 coordinator 節(jié)點(diǎn)同步過(guò)來(lái),從而使 coordinator 節(jié)點(diǎn)和 Worker 節(jié)點(diǎn)全鏈路無(wú)狀態(tài)化。

基于以上兩點(diǎn)設(shè)計(jì),PolarDB的彈性擴(kuò)展具備了以下幾大優(yōu)勢(shì):

① 任何節(jié)點(diǎn)都可以成為coordinator 節(jié)點(diǎn),解決了傳統(tǒng) MPP 數(shù)據(jù)庫(kù) coordinator 的節(jié)點(diǎn)單點(diǎn)問(wèn)題。

② PolarDB 可以橫向 Scale Out (算力彈性擴(kuò)展),也可以縱向 Scale Up (單機(jī)并行度彈性擴(kuò)展),并且彈性擴(kuò)展是及時(shí)生效的,不需要重分布數(shù)據(jù)。

③ 允許業(yè)務(wù)有更多的彈性調(diào)度策略,不同的業(yè)務(wù)閾可以運(yùn)行在不同的節(jié)點(diǎn)集合上。如上圖右側(cè)所示,業(yè)務(wù)域 SQL 1 可以選擇 RO1 和 RO2 節(jié)點(diǎn)來(lái)執(zhí)行 AP 查詢,業(yè)務(wù)域 SQL 2 可以選擇使用RO3 和 RO4 節(jié)點(diǎn)來(lái)執(zhí)行 AP 查詢。兩個(gè)業(yè)務(wù)域使用的計(jì)算節(jié)點(diǎn)可以實(shí)現(xiàn)彈性調(diào)度。

傾斜是傳統(tǒng) MPP 固有的問(wèn)題,其原因主要是數(shù)據(jù)分布傾斜和數(shù)據(jù)計(jì)算傾斜。數(shù)據(jù)分布傾斜通常由數(shù)據(jù)打散不均衡導(dǎo)致,在 PG 中還會(huì)由于大對(duì)象 toast 表存儲(chǔ)引入一些不可避免的數(shù)據(jù)分布不均衡問(wèn)題;計(jì)算傾斜通常由于不同節(jié)點(diǎn)上并發(fā)的事務(wù)、 buffer 、網(wǎng)絡(luò)、 IO 抖動(dòng)導(dǎo)致。傾斜會(huì)導(dǎo)致傳統(tǒng) MPP 在執(zhí)行時(shí)的木桶效應(yīng)。

PolarDB 設(shè)計(jì)實(shí)現(xiàn)了自適應(yīng)掃描機(jī)制。如上圖右所示,采用coordinator節(jié)點(diǎn)來(lái)協(xié)調(diào)Worker節(jié)點(diǎn)詢問(wèn)的工作模式。在掃描數(shù)據(jù)時(shí),coordinator節(jié)點(diǎn)會(huì)在內(nèi)存中創(chuàng)建一個(gè)任務(wù)管理器,根據(jù)掃描任務(wù)對(duì) Worker 節(jié)點(diǎn)進(jìn)行調(diào)度。coordinator節(jié)點(diǎn)內(nèi)部分為兩個(gè)線程,data線程主要負(fù)責(zé)服務(wù)數(shù)據(jù)鏈路、收集匯總元組,control線程負(fù)責(zé)服務(wù)控制鏈路、控制每一個(gè)掃描算子的掃描進(jìn)度。

掃描塊的 Worker 能夠掃描多個(gè)數(shù)據(jù)塊,實(shí)現(xiàn)能者多勞。比如上圖中 RO1 與RO3 的 Worker 都各自掃描了4個(gè)數(shù)據(jù)塊, ROI2由于計(jì)算傾斜可以掃描更多數(shù)據(jù)塊,因此它最終掃描了 6 個(gè)數(shù)據(jù)塊。

PolarDB 自適應(yīng)掃描機(jī)制還考慮了 PG BufferPool 的親和性,保證每個(gè) Worker 盡量掃描固定的數(shù)據(jù)塊,從而最大化命中BufferPool中的緩存,降低 IO 開(kāi)銷。

三、功能特性

經(jīng)過(guò)持續(xù)迭代的研發(fā),目前 PolarDB HTAP 在支持 Parallel Query 上支持的功能特性主要有五大部分:

① 基礎(chǔ)算子全支持。不僅包括 scan 類算子、Join類、聚合類,還包括 SubqueryScan、HashJoin 等。

② 共享存儲(chǔ)算子優(yōu)化。包括 shuffle 算子共享、ShareSeqScan 共享、 ShareIndexScan等。其中ShareSeqScan 共享、 ShareIndexScan共享是指在大表 join 小表時(shí),小表采用類似于復(fù)制表的機(jī)制來(lái)減少?gòu)V播開(kāi)銷,進(jìn)而提升性能。

③ 分區(qū)表支持。不僅包括對(duì)Hash/Range/List三種分區(qū)方式的完整支持,還包括對(duì)多級(jí)分區(qū)靜態(tài)裁剪、分區(qū)動(dòng)態(tài)裁剪的支持。除此之外,PolarDB 分布式 MPP 執(zhí)行引擎還支持分區(qū)表的Partition Wise Join。

④ 并行度彈性控制。包括全局級(jí)別、表級(jí)別、會(huì)話級(jí)別、查詢級(jí)別的并行度控制。

⑤ Serverless 彈性擴(kuò)展。不僅包括任意節(jié)點(diǎn)發(fā)起 MPP、MPP 節(jié)點(diǎn)范圍內(nèi)的任意組合,還包括集群拓?fù)湫畔⒌淖詣?dòng)維護(hù),以及支持共享存儲(chǔ)模式、主備庫(kù)模式、三節(jié)點(diǎn)模式。

既然是 HTAP ,則必然不能缺少對(duì) DML 的 MPP 支持。基于 PolarDB讀寫(xiě)分離架構(gòu)和 HTAP serverless 彈性擴(kuò)展的設(shè)計(jì), PolarDB parallel DML支持一寫(xiě)多讀、多寫(xiě)多讀兩種特性。一寫(xiě)多讀是指在 RO節(jié)點(diǎn)上有多個(gè)讀 Worker ,但在 RW節(jié)點(diǎn)上只有一個(gè)寫(xiě) Worker ;多寫(xiě)多讀是指在 RO 節(jié)點(diǎn)上有多個(gè)讀 Worker ,在 RW節(jié)點(diǎn)上也有多個(gè)寫(xiě) Worker 。多寫(xiě)多讀場(chǎng)景下,讀的并發(fā)度和寫(xiě)的并發(fā)度是完全解耦的。不同的特性適用不同的場(chǎng)景,用戶可以根據(jù)自己的業(yè)務(wù)特點(diǎn)來(lái)選擇不同的PDML功能特性。

PolarDB 分布式 MPP執(zhí)行引擎,不僅可以用于 query 和 DML ,還可以用于索引構(gòu)建加速。ALTP業(yè)務(wù)中有大量的索引,而索引創(chuàng)建過(guò)程大約有 80% 的時(shí)間消耗在排序和構(gòu)建索引頁(yè)上,20%消耗在寫(xiě)索引頁(yè)上。如右上圖, PolarDB 利用 RO 節(jié)點(diǎn)進(jìn)行數(shù)據(jù)分布式 MPP 加速排序,采用流程化的技術(shù)來(lái)構(gòu)建索引頁(yè),采用批量寫(xiě)入技術(shù)來(lái)提高索引頁(yè)的寫(xiě)入速度。

目前構(gòu)建索引加速這一特性中,PolarDB 已經(jīng)對(duì)常用 B 樹(shù)索引的普通創(chuàng)建以及 B 樹(shù)索引的在線創(chuàng)建兩種功能進(jìn)行了支持。

通過(guò)上圖與PolarDB原生的單機(jī)并行進(jìn)行對(duì)比,可以看出分布式MPP的優(yōu)勢(shì)所在。我們使用線上 PolarDB 16g 和 256g 內(nèi)存的 16 個(gè) RO 實(shí)例,搭建了 1 TB 的 TPCH 環(huán)境進(jìn)行測(cè)試對(duì)比。相比單機(jī)并行,分布式 MPP 并行充分利用了所有 RO 節(jié)點(diǎn)的計(jì)算資源和底層共享存儲(chǔ) RO 帶寬,從根本上解決了前文提到的 HTAP 挑戰(zhàn)。在 TPCH 22 條 SQL 中,有 3 條 SQL 加速了 60 多倍,19條 SQL 加速了 10 多倍,平均加速 23 倍。此外,我們也測(cè)試了彈性擴(kuò)大給計(jì)算資源帶來(lái)的變化。通過(guò)增加 CPU 總核數(shù),從 16 核增加到 128 核, TPCH 的總運(yùn)營(yíng)時(shí)間線性提升,每一個(gè) SQL 也呈線性提升,這也驗(yàn)證了 PolarDB HTAP serverless 彈性擴(kuò)展的特性。

測(cè)試中發(fā)現(xiàn),當(dāng) CPU 的總核數(shù)增加到 256 核時(shí),性能提升并不大。原因是此時(shí) PolarDB 共享存儲(chǔ)的 IO 帶寬已經(jīng)打滿,成為了瓶頸。這也從側(cè)面說(shuō)明了 PolarDB 分布式 MPP 執(zhí)行引擎的計(jì)算能力是非常強(qiáng)的。

此外,我們將 PolarDB 的分布式 MPP 與傳統(tǒng)數(shù)據(jù)庫(kù)的 MPP 進(jìn)行了對(duì)比,同樣使用 16g 和 256g 內(nèi)存的 16 個(gè)節(jié)點(diǎn)。 1 TB 的 TPCH 數(shù)據(jù)在保持與傳統(tǒng) MPP 數(shù)據(jù)庫(kù)相同的單機(jī)并行度為 1 的情況下,PolarDB的性能是傳統(tǒng) MPP 數(shù)據(jù)庫(kù)的90%。其中最本質(zhì)的原因是傳統(tǒng) MPP 數(shù)據(jù)庫(kù)的分布默認(rèn)是哈希分布,當(dāng)兩張表的joinkey 是各自的分布鍵時(shí),可以不用 shuffle 直接進(jìn)行 Local Wise Join 。而 PolarDB 底層是共享存儲(chǔ)池, PxScan 并行掃描出來(lái)的數(shù)據(jù)等價(jià)于隨機(jī)分布,必須 shuffle 重分布后才能像傳統(tǒng) MPP 數(shù)據(jù)庫(kù)一樣進(jìn)行后續(xù)的處理。因此, TPCH 涉及到表join時(shí), PolarDB 相比傳統(tǒng) MPP 數(shù)據(jù)庫(kù)多了一次網(wǎng)絡(luò) shuffle 的開(kāi)銷。

PolarDB分布式 MPP 能夠進(jìn)行彈性擴(kuò)展,數(shù)據(jù)不需要重分布。因此在這有限的 16 臺(tái)機(jī)器上執(zhí)行 MPP 時(shí),PolarDB 還可以繼續(xù)擴(kuò)展單機(jī)并行度,充分利用機(jī)器的資源;當(dāng) PolarDB的單機(jī)并行度為 8 時(shí),它的性能是傳統(tǒng) MPP 數(shù)據(jù)庫(kù)的 5-6 倍;當(dāng) PolarDB單機(jī)并行度呈線性增加時(shí),PolarDB總的性能也呈線性增加,只需要修改配置參數(shù),即可及時(shí)生效。

針對(duì)PolarDB HTAP 對(duì)構(gòu)建索引加速特性的支持,我們也進(jìn)行了性能測(cè)試。在 500 GB 的數(shù)據(jù)量下,當(dāng)索引的字段有1、2、4個(gè)時(shí),分布式 MPP 并行相比單機(jī)并行構(gòu)建索引性能提升了5倍左右;當(dāng)構(gòu)建索引的字段增加到8個(gè)時(shí),性能提升了4倍左右。

原文鏈接

本文為阿里云原創(chuàng)內(nèi)容,未經(jīng)允許不得轉(zhuǎn)載。?

創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來(lái)咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)

總結(jié)

以上是生活随笔為你收集整理的阿里云数据库开源发布:PolarDB HTAP的功能特性和关键技术的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。