重復數(shù)據(jù)刪除(De-duplication)技術(shù)研究_第1頁
重復數(shù)據(jù)刪除(De-duplication)技術(shù)研究_第2頁
重復數(shù)據(jù)刪除(De-duplication)技術(shù)研究_第3頁
重復數(shù)據(jù)刪除(De-duplication)技術(shù)研究_第4頁
重復數(shù)據(jù)刪除(De-duplication)技術(shù)研究_第5頁
已閱讀5頁,還剩16頁未讀 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領

文檔簡介

1、重復數(shù)據(jù)刪除(De-duplication技術(shù)研究 1、Dedupe概述De-duplication,即重復數(shù)據(jù)刪除,它是一種目前主流且非常熱門的存儲技術(shù),可對存儲容量進行有效優(yōu)化。它通過刪除數(shù)據(jù)集中重復的數(shù) 據(jù),只保留其中一份,從而消除冗余數(shù)據(jù)。如下圖所示。這種技術(shù)可以很大程度上減少對物理存儲空間的需求,從而滿足日益增長的數(shù)據(jù)存儲需求。Dedupe技 術(shù)可以帶許多實際的利益,主要包括以下諸多方面:(1 滿足ROI(投資回報率,Return On Investment/TCO(總持有成本,Total Cost of Ownership需求;(2 可以有效控制數(shù)據(jù)的急劇增長; (3 增

2、加有效存儲空間,提高存儲效率;(4 節(jié)省存儲總成本和管理成本;(5 節(jié)省數(shù)據(jù)傳輸?shù)木W(wǎng)絡帶寬;(6 節(jié)省空間、電力供應、冷卻等運維成本。Dedupe技術(shù)目前大量應用于數(shù)據(jù)備份與歸檔系統(tǒng),因為對數(shù)據(jù)進行多次備份后,存在大量重復數(shù)據(jù),非常適合這種技術(shù)。事實上,dedupe技術(shù) 可以用于很多場合,包括在線數(shù)據(jù)、近線數(shù)據(jù)、離線數(shù)據(jù)存儲系統(tǒng),可以在文件系統(tǒng)、卷管理器、NAS、SAN中實施。Dedupe也可以用于數(shù)據(jù)容災、數(shù)據(jù) 傳輸與同步,作為一種數(shù)據(jù)壓縮技術(shù)可用于數(shù)據(jù)打包。Dedupe技術(shù)可以幫助眾多應用降低數(shù)據(jù)存儲量,節(jié)省網(wǎng)絡帶寬,提高存儲效率、減小備份窗口,節(jié)省成 本。Dedupe的衡量維度主要有兩個

3、,即重復數(shù)據(jù)刪除率(deduplocation ratios和性能。Dedupe性能取決于具體實現(xiàn)技術(shù),而重復數(shù)據(jù)刪除率則由數(shù)據(jù)自身的特征和應用模式所決定,影響因素如下表2所示。目前各存 儲廠商公布的重復數(shù)據(jù)刪除率從20:1到500:1不等。高重復數(shù)據(jù)刪除率低重復數(shù)據(jù)刪除率數(shù)據(jù)由用戶創(chuàng)建數(shù)據(jù)從自然世界獲取數(shù)據(jù)低變化率數(shù)據(jù)高變化率引用數(shù)據(jù)、非活動數(shù)據(jù)活動數(shù)據(jù)低數(shù)據(jù)變化率應用高數(shù)據(jù)變化率應用完全數(shù)據(jù)備份增量數(shù)據(jù)備份數(shù)據(jù)長期保存數(shù)據(jù)短期保存大范圍數(shù)據(jù)應用小范圍數(shù)據(jù)應用持續(xù)數(shù)據(jù)業(yè)務處理普通數(shù)據(jù)業(yè)務處理小數(shù)據(jù)分塊大數(shù)據(jù)分塊變長數(shù)據(jù)分塊定長數(shù)據(jù)分塊數(shù)據(jù)內(nèi)容可感知數(shù)據(jù)內(nèi)容不可知時間數(shù)據(jù)消重空間數(shù)據(jù)消重2、D

4、edupe實現(xiàn)要點研發(fā)或應用Dedupe技術(shù)時應該考慮各種因素,因為這些因素會直接影響其性能和效果。(1 What:對何種數(shù)據(jù)進行消重?對時間數(shù)據(jù)還是空間數(shù)據(jù)進行消重,對全局數(shù)據(jù)還是局部數(shù)據(jù) 進行消重?這是首先需要考慮的因素,這直接決定著Dedupe實現(xiàn)技術(shù)和數(shù)據(jù)消重率。隨時間變化的數(shù)據(jù),如周期性的備份、歸檔數(shù)據(jù),比空間數(shù)據(jù)具有更高的 消重率,Dedupe技術(shù)在備份歸檔領域中被廣泛應用。不難想象,全局范圍內(nèi)的數(shù)據(jù)重復率比局部范圍數(shù)據(jù)要高,會獲得更高的數(shù)據(jù)消重率。(2 When:何時進行消重?數(shù)據(jù)消重時機分為兩種情形:在線消重和離線消重。采用在線消重模 式,數(shù)據(jù)寫入存儲系統(tǒng)同時執(zhí)行消重,因此實際

5、傳輸或?qū)懭氲臄?shù)據(jù)量較少,適合通過LAN或WAN進行數(shù)據(jù)處理的存儲系統(tǒng),如網(wǎng)絡備份歸檔和異地容災系統(tǒng)。由 于它需要實時進行文件切分、數(shù)據(jù)指紋計算、Hash查找,對系統(tǒng)資料消耗大。離線消重模式,先將數(shù)據(jù)寫入存儲系統(tǒng),然后利用適當?shù)臅r間再進行消重處理。這 種模式與前面一種剛好相反,它對系統(tǒng)資料消耗少,但寫入了包含重復的數(shù)據(jù),需要更多的額外存儲空間來預先存儲消重前數(shù)據(jù)。這種模式適合直連存儲DAS和存 儲區(qū)域網(wǎng)絡SAN存儲架構(gòu),數(shù)據(jù)傳輸不占用網(wǎng)絡帶寬。另外,離線消重模式需要保證有足夠的時間窗口來進行數(shù)據(jù)去重操作。總之,在何時進行消重,要根據(jù)實際 存儲應用場景來確定。(3 Where:在何處進行消重?數(shù)據(jù)

6、消重可以在源端(Source或者目標端 (Target進行。源端消重在數(shù)據(jù)源進行,傳輸?shù)氖且呀?jīng)消重后的數(shù)據(jù),能夠節(jié)省網(wǎng)絡帶寬,但會占用大量源端系統(tǒng)資源。目標端消重發(fā)生在目標端,數(shù)據(jù)在 傳輸?shù)侥繕硕嗽龠M行消重,它不會占用源端系統(tǒng)資源,但占用大量網(wǎng)絡帶寬。目標端消重的優(yōu)勢在于它對應用程序透明,并具有良好的互操作性,不需要使用專門的 API,現(xiàn)有應用軟件不用作任何修改即可直接應用。(4 How:如何進行消重?重復數(shù)據(jù)刪除技術(shù)包含許多技術(shù)實現(xiàn)細節(jié),包括文件如何進行切分?數(shù) 據(jù)塊指紋如何計算?如何進行數(shù)據(jù)塊檢索?采用相同數(shù)據(jù)檢測還是采用相似數(shù)據(jù)檢測和差異編碼技術(shù)?數(shù)據(jù)內(nèi)容是否可以感知,是否需要對內(nèi)容進行

7、解析?這些都是 Dedupe具體實現(xiàn)息息相關。本文主要研究相同數(shù)據(jù)檢測技術(shù),基于二進制文件進行消重處理,具有更廣泛的適用性。3、Dedupe關鍵技術(shù)存儲系統(tǒng)的重復數(shù)據(jù)刪除過程一般是這樣的:首先將數(shù)據(jù)文件分割成一組數(shù)據(jù)塊,為每個數(shù)據(jù)塊計算指紋,然后以指紋為關鍵字進行Hash查找,匹配則 表示該數(shù)據(jù)塊為重復數(shù)據(jù)塊,僅存儲數(shù)據(jù)塊索引號,否則則表示該數(shù)據(jù)塊是一個新的唯一塊,對數(shù)據(jù)塊進行存儲并創(chuàng)建相關元信息。這樣,一個物理文件在存儲系統(tǒng) 就對應一個邏輯表示,由一組FP組成的元數(shù)據(jù)。當進行讀取文件時,先讀取邏輯文件,然后根據(jù)FP序列,從存儲系統(tǒng)中取出相應數(shù)據(jù)塊,還原物理文件副本。從 如上過程中可以看出,D

8、edupe的關鍵技術(shù)主要包括文件數(shù)據(jù)塊切分、數(shù)據(jù)塊指紋計算和數(shù)據(jù)塊檢索。(1 文件數(shù)據(jù)塊切分Dedupe按照消重的粒度可以分為文件級和數(shù)據(jù)塊級。文件級的dedupe技術(shù)也稱為單一實例存儲(SIS, Single Instance Store,數(shù)據(jù)塊級的重復數(shù)據(jù)刪除其消重粒度更小,可以達到4-24KB之間。顯然,數(shù)據(jù)塊級的可以提供更高的數(shù)據(jù)消重率,因此目前主流的 dedupe產(chǎn)品都是數(shù)據(jù)塊級的。數(shù)據(jù)分塊算法主要有三種,即定長切分(fixed-size partition、CDC切分(content-defined chunking和滑動塊(sliding block切分。定長分塊算法采用預先義好

9、的塊大小對文件進行切分,并進行弱校驗值和md5強校驗值。弱校驗值主要是為了提升差異編碼的性能,先計算弱 校驗值并進行hash查找,如果發(fā)現(xiàn)則計算md5強校驗值并作進一步hash查找。由于弱校驗值計算量要比md5小很多,因此可以有效提高編碼性能。定長 分塊算法的優(yōu)點是簡單、性能高,但它對數(shù)據(jù)插入和刪除非常敏感,處理十分低效,不能根據(jù)內(nèi)容變化作調(diào)整和優(yōu)化。Deduputil中FSP分塊算法代碼如 下。  1. /* 2.  * fixed-sized file chunking  3.  */

10、60; 4. static int file_chunk_fsp(int fd, int fd_ldata, int fd_bdata, unsigned int *pos, unsigned int *block_num,   5.     block_id_t *metadata, hashtable *htable, char *l

11、ast_block_buf, unsigned int *last_block_len  6.   7.     int ret = 0;  8.     unsigned int rwsize;  9.     unsigned char md5_checksum16 + 1&

12、#160;= 0;  10.     char *buf = NULL;  11.   12.     buf = (char *malloc(g_block_size;  13.     if (buf = NULL  14.     &

13、#160; 15.         perror("malloc in file_chunk_fsp"  16.         return errno;  17.       18.   19.     while&

14、#160;(rwsize = read(fd, buf, g_block_size  20.           21.                 /* if the last block */  22.

15、                 if (rwsize != g_block_size  23.                         br

16、eak;  24.   25.                 /* calculate md5 */  26.                 md5(buf, rwsize,&

17、#160;md5_checksum;  27.         if (0 != (ret = dedup_regfile_block_process(buf, rwsize, md5_checksum, fd_ldata,   28.             fd_b

18、data, pos, block_num, metadata, htable  29.           30.             perror("dedup_regfile_block_process in file_chunk_fsp"  31.

19、            goto _FILE_CHUNK_FSP_EXIT;  32.           33.       34.     *last_block_len = (rwsize > 0&

20、#160;? rwsize : 0;  35.     if (*last_block_len memcpy(last_block_buf, buf, *last_block_len;  36.   37. _FILE_CHUNK_FSP_EXIT:  38.     if (buf free(buf;  39.  &

21、#160;  return ret;  40.   CDC(content-defined chunking算法是一種變長分塊算法,它應用數(shù)據(jù)指紋(如Rabin指紋將文件分割成長度大小不等的分塊策略。與定長分塊算法不同,它是基于文件 內(nèi)容進行數(shù)據(jù)塊切分的,因此數(shù)據(jù)塊大小是可變化的。算法執(zhí)行過程中,CDC使用一個固定大小(如48字節(jié)的滑動窗口對文件數(shù)據(jù)計算數(shù)據(jù)指紋。如果指紋滿 足某個條件,如當它的值模特定的整數(shù)等于預先設定的數(shù)時,則把窗口位置作為塊的邊界。CDC算法可能會出現(xiàn)病態(tài)現(xiàn)象,即指紋條件不能滿足,塊邊界不能確 定,導致

22、數(shù)據(jù)塊過大。實現(xiàn)中可以對數(shù)據(jù)塊的大小進行限定,設定上下限,解決這種問題。CDC算法對文件內(nèi)容變化不敏感,插入或刪除數(shù)據(jù)只會影響到檢少的數(shù) 據(jù)塊,其余數(shù)據(jù)塊不受影響。CDC算法也是有缺陷的,數(shù)據(jù)塊大小的確定比較困難,粒度太細則開銷太大,粒度過粗則dedup效果不佳。如何兩者之間權(quán)衡折 衷,這是一個難點。Deduputil中CDC分塊算法代碼如下。 1. /* 2.  * content-defined chunking: 3.  * 1. BLOCK_MIN_SIZE <= blo

23、ck_size <= BLOCK_MAX_SIZE 4.  * 2. hash(block % d = r 5.  */  6. static int file_chunk_cdc(int fd, int fd_ldata, int fd_bdata, unsigned int *pos, unsigned int *bl

24、ock_num,  7.     block_id_t *metadata, hashtable *htable, char *last_block_buf, unsigned int *last_block_len  8.   9.     char bufBUF_MAX_SIZE = 0;  10.   

25、  char block_bufBLOCK_MAX_SIZE = 0;  11.     char win_bufBLOCK_WIN_SIZE + 1 = 0;  12.     char adler_pre_char;  13.     unsigned char md5_checksu

26、m16 + 1 = 0;  14.     unsigned int bpos = 0;  15.     unsigned int rwsize = 0;  16.     unsigned int exp_rwsize = BUF_MAX_SIZE;

27、60; 17.     unsigned int head, tail;  18.     unsigned int block_sz = 0, old_block_sz = 0;  19.     unsigned int hkey = 0;  20.  &

28、#160;  int ret = 0;  21.   22.     while(rwsize = read(fd, buf + bpos, exp_rwsize  23.       24.         /* last ch

29、unk */  25.         if (rwsize + bpos + block_sz < BLOCK_MIN_SIZE  26.             break;  27.   28.   

30、0;     head = 0;  29.         tail = bpos + rwsize;  30.         /* avoid unnecessary computation and comparsion */

31、  31.         if (block_sz < (BLOCK_MIN_SIZE - BLOCK_WIN_SIZE  32.           33.             old_block

32、_sz = block_sz;  34.             block_sz = (block_sz + tail - head > (BLOCK_MIN_SIZE - BLOCK_WIN_SIZE ?   35.       

33、              BLOCK_MIN_SIZE - BLOCK_WIN_SIZE : block_sz + tail -head;    36.             memcpy(block_buf +&#

34、160;old_block_sz, buf + head, block_sz - old_block_sz;  37.             head += (block_sz - old_block_sz;  38.           

35、;39.   40.         while (head + BLOCK_WIN_SIZE <= tail  41.           42.             memcpy(win_buf,

36、 buf + head, BLOCK_WIN_SIZE;  43.             /* 44.              * Firstly, i think rabinhash is the bes

37、t. However, it's performance is very bad. 45.              * After some testing, i found ELF_hash is better both on performance and 

38、;dedup rate. 46.              * So, EFL_hash is default. Now, adler_hash as default. 47.              */  

39、;48.             if (g_rolling_hash  49.               50.                 

40、hkey = (block_sz = (BLOCK_MIN_SIZE - BLOCK_WIN_SIZE ? adler32_checksum(win_buf, BLOCK_WIN_SIZE :  51.                     adler32_rolling_ch

41、ecksum(hkey, BLOCK_WIN_SIZE, adler_pre_char, bufhead+BLOCK_WIN_SIZE-1;  52.                53.             else   54.  &

42、#160;              hkey = g_cdc_chunk_hashfunc(win_buf;  55.   56.             /* get a normal chunk */  

43、p 57.             if (hkey % g_block_size = CHUNK_CDC_R   58.               p 59.          

44、;       memcpy(block_buf + block_sz, buf + head, BLOCK_WIN_SIZE;   60.                 head += BLOCK_WIN_SIZE;  p 61.  &

45、#160;              block_sz += BLOCK_WIN_SIZE;   62.                 if (block_sz >= BLOCK_MIN_SIZE  6

46、3.                   64.                     md5(block_buf, block_sz, md5_checksum;  65. &

47、#160;                   if (0 != (ret = dedup_regfile_block_process(block_buf, block_sz,   66.            

48、;             md5_checksum, fd_ldata, fd_bdata, pos, block_num, metadata, htable  67.                   &

49、#160;   68.                         perror("dedup_reggile_block_process in file_chunk_cdc"  69.       

50、60;                 goto _FILE_CHUNK_CDC_EXIT;  70.                       71.   

51、                  block_sz = 0;  72.                   73.        

52、;       74.             else   75.               76.            &

53、#160;    block_bufblock_sz+ = bufhead+;  77.                 /* get an abnormal chunk */  78.         

54、60;       if (block_sz >= BLOCK_MAX_SIZE  79.                   80.              &

55、#160;      md5(block_buf, block_sz, md5_checksum;  81.                     if (0 != (ret = dedup_regfile_block_process(block_

56、buf, block_sz,   82.                         md5_checksum, fd_ldata, fd_bdata, pos, block_num, metadata, htable  83. 

57、60;                     84.                         perror("dedup_regg

58、ile_block_process in file_chunk_cdc"  85.                         goto _FILE_CHUNK_CDC_EXIT;  86.        

59、               87.                     block_sz = 0;  88.         

60、;          89.               90.   91.             /* avoid unnecessary computation and

61、60;comparsion */  92.             if (block_sz = 0  93.               94.          &#

62、160;      block_sz = (tail - head > (BLOCK_MIN_SIZE - BLOCK_WIN_SIZE ?   95.                     BLOCK_MIN_

63、SIZE - BLOCK_WIN_SIZE : tail - head;  96.                 memcpy(block_buf, buf + head, block_sz;  97.         

64、;        head = (tail - head > (BLOCK_MIN_SIZE - BLOCK_WIN_SIZE ?   98.                     head&

65、#160;+ (BLOCK_MIN_SIZE - BLOCK_WIN_SIZE : tail;  99.               100.   101.             adler_pre_char = bufhead

66、 -1;  102.           103.   104.         /* read expected data from file to full up buf */  105.     

67、0;   bpos = tail - head;  106.         exp_rwsize = BUF_MAX_SIZE - bpos;  107.         adler_pre_char = bufhead -1;  108

68、.         memmove(buf, buf + head, bpos;  109.       110.     /* last chunk */  111.     *last_block_len = (rwsize +

69、0;bpos + block_sz >= 0 ? rwsize + bpos + block_sz : 0;  112.     if (*last_block_len > 0  113.       114.        &

70、#160;memcpy(last_block_buf, block_buf, block_sz;  115.         memcpy(last_block_buf + block_sz, buf, rwsize + bpos;  116.       117.   118. _FILE_CHUNK_CDC_EXI

71、T:  119.     return ret;  120.    滑動塊(sliding block算法結(jié)合了定長切分和CDC切分的優(yōu)點,塊大小固定。它對定長數(shù)據(jù)塊先計算弱校驗值,如果匹配則再計算md5強校驗值,兩者都匹配則認為是一 個數(shù)據(jù)塊邊界。該數(shù)據(jù)塊前面的數(shù)據(jù)碎片也是一個數(shù)據(jù)塊,它是不定長的。如果滑動窗口移過一個塊大小的距離仍無法匹配,則也認定為一個數(shù)據(jù)塊邊界。滑動塊算 法對插入和刪除問題處理非常高效,并且能夠檢測到比CDC更多的冗余數(shù)據(jù),它的不足是容易產(chǎn)生數(shù)據(jù)碎片。

72、Deduputil中SB分塊算法代碼如下。 1. /* 2.  * slideing block chunking, performance is a big issue due to too many hash lookup. 3.  */  4. static int file_chunk_sb(int fd, int fd_ldat

73、a, int fd_bdata, unsigned int *pos, unsigned int *block_num,  5.          block_id_t *metadata, hashtable *htable, char *last_block_buf, unsigned int *last_block_len

74、  6.   7.     char bufBUF_MAX_SIZE = 0;  8.     char win_bufBLOCK_MAX_SIZE + 1 = 0;  9.     char block_bufBLOCK_MAX_SIZE = 0;  10. 

75、0;   char adler_pre_char;  11.     unsigned char md5_checksum16 + 1 = 0;  12.     unsigned char md5_checksum116 + 1 = 0;  13.     

76、unsigned char crc_checksum16 = 0;  14.     unsigned int bpos = 0;  15.     unsigned int slide_sz = 0;  16.     unsigned int rwsize =

77、60;0;  17.     unsigned int exp_rwsize = BUF_MAX_SIZE;  18.     unsigned int head, tail;  19.     unsigned int hkey = 0;  20.    &

78、#160;unsigned int bflag = 0;  21.     int ret = 0;  22.   23.     while(rwsize = read(fd, buf + bpos, exp_rwsize  24.       2

79、5.         /* last chunk */  26.         if (rwsize + bpos + slide_sz < g_block_size  27.          

80、60;  break;  28.   29.         head = 0;  30.         tail = bpos + rwsize;  31.         while 

81、(head + g_block_size <= tail  32.           33.             memcpy(win_buf, buf + head, g_block_size;  34.    &#

82、160;        hkey = (slide_sz = 0 ? adler32_checksum(win_buf, g_block_size :   35.                 adler32_rolling_checksum(hk

83、ey, g_block_size, adler_pre_char, bufhead+g_block_size-1;  36.             uint_2_str(hkey, crc_checksum;  37.             bflag = 

84、;0;  38.   39.             /* this block maybe is duplicate */  40.             if (hash_exist(g_sb_htable_crc,

85、0;crc_checksum  41.                  42.                 bflag = 2;  43.      &#

86、160;          md5(win_buf, g_block_size, md5_checksum;  44.                 if (hash_exist(htable, md5_checksum  45.   &

87、#160;               46.                     /* insert fragment */  47.      

88、;               if (slide_sz != 0  48.                       49.     &

89、#160;                   md5(block_buf, slide_sz, md5_checksum1;  50.                    &#

90、160;    if (0 != (ret = dedup_regfile_block_process(block_buf, slide_sz, md5_checksum1,   51.                       

91、0;     fd_ldata, fd_bdata, pos, block_num, metadata, htable  52.                           53.   

92、60;                         perror("dedup_regfile_block_process in file_chunk_sb"  54.          

93、0;                  goto _FILE_CHUNK_SB_EXIT;  55.                         

94、  56.                       57.                     /* insert fixed-si

95、ze block */  58.                     if (0 != (ret = dedup_regfile_block_process(win_buf, g_block_size, md5_checksum,   59.  

96、                       fd_ldata, fd_bdata, pos, block_num, metadata, htable  60.            

97、60;          61.                         perror("dedup_regfile_block_process in file_chunk_sb"  62.

98、                        goto _FILE_CHUNK_SB_EXIT;  63.                   &#

99、160;   64.   65.                     head += g_block_size;  66.                &

100、#160;    slide_sz = 0;  67.                     bflag = 1;  68.             

101、0;     69.               70.   71.             /* this block is not duplicate */  72.  

102、60;          if (bflag != 1  73.               74.                 block_bu

103、fslide_sz = bufhead;  75.                 head+;  76.                 slide_sz+;  77.   &#

104、160;             if (slide_sz = g_block_size  78.                   79.         

105、            if (bflag != 2 md5(block_buf, g_block_size, md5_checksum;  80.                     if

106、60;(0 != (ret = dedup_regfile_block_process(block_buf, g_block_size, md5_checksum,   81.                         fd_ldata, fd_bdat

107、a, pos, block_num, metadata, htable  82.                       83.                

108、60;        perror("dedup_regfile_block_process in file_chunk_sb"  84.                         goto _FILE_

109、CHUNK_SB_EXIT;  85.                       86.                     hash_checkin(g

110、_sb_htable_crc, crc_checksum;  87.                     slide_sz = 0;  88.                   89.               90.  

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論