欧美一级特黄大片做受成人-亚洲成人一区二区电影-激情熟女一区二区三区-日韩专区欧美专区国产专区

RoecketMQ存儲中如何實現(xiàn)映射文件預熱

這篇文章將為大家詳細講解有關RoecketMQ存儲中如何實現(xiàn)映射文件預熱,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。

成都創(chuàng)新互聯(lián)公司主打移動網站、成都網站建設、成都網站制作、網站改版、網絡推廣、網站維護、域名注冊、等互聯(lián)網信息服務,為各行業(yè)提供服務。在技術實力的保障下,我們?yōu)榭蛻舫兄Z穩(wěn)定,放心的服務,根據網站的內容與功能再決定采用什么樣的設計。最后,要實現(xiàn)符合網站需求的內容、功能與設計,我們還會規(guī)劃穩(wěn)定安全的技術方案做保障。

一、問題描述

1.為什么創(chuàng)建文件(commitLog)時要預熱?
2.為什么要寫入1G大小的假值(0)呢?
3.為什么要鎖定內存?
4.預熱流程是怎么樣的?

二、調用鏈
@1 AllocateMappedFileService#mmapOperation
// pre write mappedFile
if (mappedFile.getFileSize() >= this.messageStore.getMessageStoreConfig()
.getMapedFileSizeCommitLog() && this.messageStore.getMessageStoreConfig().isWarmMapedFileEnable()) {
//預熱
mappedFile.warmMappedFile(
this.messageStore.getMessageStoreConfig().getFlushDiskType(),
this.messageStore.getMessageStoreConfig()
.getFlushLeastPagesWhenWarmMapedFile()
);
}
@2 MappedFilewarmMappedFile
三、流程圖

RoecketMQ存儲中如何實現(xiàn)映射文件預熱

四、代碼驗證

在文件預熱時為什么將1G假值(0)寫入文件呢?不寫這些值會怎么樣呢?
將預熱代碼改造下做個測試:分別映射空文件和將文件寫入1G假值0,觀察內存映射變化。

1.文件映射測試代碼

public static void main(String [] args) throws Exception {
File file = new File(args[0]);
FileChannel fileChannel = new RandomAccessFile(file, "rw").getChannel();
MappedByteBuffer mappedByteBuffer = fileChannel.map(FileChannel.MapMode.READ_WRITE, 0, 1024 * 1024 * 1024);
if(args.length >1 && args[1]!=null && Boolean.parseBoolean(args[1])){
for (int i = 0, j = 0; i < 1024 * 1024 * 1024; i += 1024 * 4, j++) {
mappedByteBuffer.put(i, (byte) 0);
}
}
final long address = ((DirectBuffer) (mappedByteBuffer)).address();
Pointer pointer = new Pointer(address);
{
int ret = LibC.INSTANCE.mlock(pointer, new NativeLong(1024 * 1024 * 102));
}
{
int ret = LibC.INSTANCE.madvise(pointer, new NativeLong(1024 * 1024 * 102), LibC.MADV_WILLNEED);
}
Thread.sleep(1000000000);
}

2.映射空文件
新建文件x.tmp,此文件為空,映射到內存會發(fā)生什么呢?
運行例子程序

java -jar melontst2.jar x.tmp

查看虛擬內存映射

cat /proc/xxx-pid/maps
7f4c48000000-7f4c88000000 rw-s 00000000 fd:00 395167 /home/baseuser/x.tmp

小結:
7f4c88000000-7f4c48000000 = 139966675943424 - 139965602201600
= 1024 * 1024 * 1024 = 1G。即:雖然是空文件,內存映射大小依然是1G大小。


3.映射1G文件

新建文件y.tmp, 寫入大小為1G字節(jié)0的數據,映射到內存會發(fā)生什么呢?
運行例子程序

java -jar melontst2.jar y.tmp true

查看虛擬內存映射

cat /proc/xxx-pid/maps
7f36e4000000-7f3724000000 rw-s 00000000 fd:00 395900 /home/baseuser/y.tmp

小結:內存映射大小計算
7f3724000000-7f36e4000000=139874803908608-139873730166784
=1073741824 = 1024 * 1024 * 1024 = 1G 內存分配了1G大小。


4.思考

既然空文件和寫入1G字節(jié)虛擬內存映射都是1G大小,寫入1G大小的意義呢?
使用mmap()內存分配時,只是建立了進程虛擬地址空間,并沒有分配虛擬內存對應的物理內存。當進程訪問這些沒有建立映射關系的虛擬內存時,處理器自動觸發(fā)一個缺頁異常,進而進入內核空間分配物理內存、更新進程緩存表,最后返回用戶空間,回復進程運行。


小結:寫入這些假值的意義在于實際分配物理內存,在消息寫入時防止缺頁異常。

5.內存映射簡圖

RoecketMQ存儲中如何實現(xiàn)映射文件預熱

虛擬內存
計算機系統(tǒng)內存管理的一種技術。它使得應用程序認為它擁有連續(xù)的可用的內存(一個連續(xù)完整的地址空間),而實際上,它通常是被分隔成多個物理內存碎片,還有部分暫時存儲在外部磁盤存儲器上,在需要時進行數據交換
虛擬地址空間的內部又被分為內核空間和用戶空間兩部分,進程在用戶態(tài)時,只能訪問用戶空間內存;只有進入內核態(tài)后,才可以訪問內核空間內存

MMU
MMU是Memory Management Unit的縮寫,中文名是內存管理單元,它是中央處理器(CPU)中用來管理虛擬存儲器、物理存儲器的控制線路,同時也負責虛擬地址映射為物理地址

頁表
是虛擬內存系統(tǒng)用來存儲邏輯地址和物理地址之間映射的數據結構

內存映射mmap
將虛擬地址映射到物理地址

五、Native API解釋

mmap
映射文件或設備到內存
void mmap(void start, size_t length, int prot, int flags, int fd, off_t offset);
The mmap() function asks to map length bytes starting at offset offset from the file (or other object) specified by the file descriptor fd into memory, preferably at address start. This latter address is a hint only, and is usually specified as 0. The actual place where the object is mapped is returned by mmap().

mlock
鎖定內存
int mlock(const void
addr, size_t len);
mlock() locks pages in the address range starting at addr and continuing for len bytes. All pages that contain a part of the specified address range are guaranteed to be resident in RAM when the call returns successfully; the pages are guaranteed to stay in RAM until later unlocked.

madvise
提出建議關于使用內存
int madvise(void *start, size_t length, int advice);
The madvise() system call advises the kernel about how to handle paging input/output in the address range beginning at address start and with size length bytes. It allows an application to tell the kernel how it expects to use some mapped or shared memory areas, so that the kernel can choose appropriate read-ahead and caching techniques. This call does not influence the semantics of the application (except in the case ofMADV_DONTNEED), but may influence its performance. The kernel is free to ignore the advice。
MADV_WILLNEED模式(MappedFile預熱使用該模式)
MADV_WILLNEED:Expect access in the near future. (Hence, it might be a good idea to read some pages ahead.)

六、總結

1.Broker配置warmMapedFileEnable為false,開啟預熱需要設置true。
2.寫入1G字節(jié)假值0是為了讓系統(tǒng)分配物理內存空間,如果沒有這些假值,系統(tǒng)不會實際分配物理內存,防止在寫入消息時發(fā)生缺頁異常。
3.mlock鎖定內存,防止其被交換到swap空間。
4.madvise建議操作系統(tǒng)如何使用內存,MADV_WILLNEED提前預熱,預讀一些頁面,提高性能。
5.文件預熱使得內存提前分配,并鎖定在內存中,在寫入消息時不必再進行內存分配。

七、附錄源代碼

1.文件初始化源代碼

private void init(final String fileName, final int fileSize) throws IOException {
this.fileName = fileName;
this.fileSize = fileSize;
this.file = new File(fileName);
this.fileFromOffset = Long.parseLong(this.file.getName());//文件名代表該文件的起始偏移量
boolean ok = false;
ensureDirOK(this.file.getParent());
try {
//通過RandomAccessFile創(chuàng)讀寫文件通道
this.fileChannel = new RandomAccessFile(this.file, "rw").getChannel();
//將文件內容通過NIO的內存映射Buffer,將文件映射到內存
//將磁盤文件讀到內存中,每個文件大小為1G
this.mappedByteBuffer = this.fileChannel.map(MapMode.READ_WRITE, 0, fileSize);
TOTAL_MAPPED_VIRTUAL_MEMORY.addAndGet(fileSize);
TOTAL_MAPPED_FILES.incrementAndGet();
ok = true;
} catch (FileNotFoundException e) {
log.error("create file channel " + this.fileName + " Failed. ", e);
throw e;
} catch (IOException e) {
log.error("map file " + this.fileName + " Failed. ", e);
throw e;
} finally {
if (!ok && this.fileChannel != null) {
this.fileChannel.close();
}
}
}

2.預熱源代碼

public void warmMappedFile(FlushDiskType type, int pages) {
long beginTime = System.currentTimeMillis();
ByteBuffer byteBuffer = this.mappedByteBuffer.slice();
int flush = 0; //記錄上一次刷盤的字節(jié)數
long time = System.currentTimeMillis();
for (int i = 0, j = 0; i < this.fileSize; i += MappedFile.OS_PAGE_SIZE, j++) {
byteBuffer.put(i, (byte) 0);
// force flush when flush disk type is sync
//當刷盤策略為同步刷盤時,執(zhí)行強制刷盤
//每修改pages個分頁刷一次盤 內存頁的大小為4K
if (type == FlushDiskType.SYNC_FLUSH) {
if ((i / OS_PAGE_SIZE) - (flush / OS_PAGE_SIZE) >= pages) {
flush = i;
mappedByteBuffer.force();
}
}
// prevent gc
//Linux CPU調度策略基于時間片 Thread.sleep 當前線程主動放棄CPU資源,立即進入就緒狀態(tài)
//防止一直搶占CPU資源不釋放
if (j % 1000 == 0) {
log.info("j={}, costTime={}", j, System.currentTimeMillis() - time);
time = System.currentTimeMillis();
try {
Thread.sleep(0);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
// force flush when prepare load finished
if (type == FlushDiskType.SYNC_FLUSH) {
log.info("mapped file warm-up done, force to disk, mappedFile={}, costTime={}",
this.getFileName(), System.currentTimeMillis() - beginTime);
mappedByteBuffer.force();
}
log.info("mapped file warm-up done. mappedFile={}, costTime={}", this.getFileName(),
System.currentTimeMillis() - beginTime);
this.mlock();
}

3.內存鎖定代碼

public void mlock() {
final long beginTime = System.currentTimeMillis();
final long address = ((DirectBuffer) (this.mappedByteBuffer)).address();
Pointer pointer = new Pointer(address);
{
//鎖死
int ret = LibC.INSTANCE.mlock(pointer, new NativeLong(this.fileSize));
log.info("mlock {} {} {} ret = {} time consuming = {}", address, this.fileName, this.fileSize, ret, System.currentTimeMillis() - beginTime);
}
{
int ret = LibC.INSTANCE.madvise(pointer, new NativeLong(this.fileSize), LibC.MADV_WILLNEED);
log.info("madvise {} {} {} ret = {} time consuming = {}", address, this.fileName, this.fileSize, ret, System.currentTimeMillis() - beginTime);
}
}

關于“RoecketMQ存儲中如何實現(xiàn)映射文件預熱”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,使各位可以學到更多知識,如果覺得文章不錯,請把它分享出去讓更多的人看到。

當前題目:RoecketMQ存儲中如何實現(xiàn)映射文件預熱
文章鏈接:http://aaarwkj.com/article30/iiheso.html

成都網站建設公司_創(chuàng)新互聯(lián),為您提供面包屑導航、網站排名、品牌網站制作、品牌網站設計定制網站、做網站

廣告

聲明:本網站發(fā)布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創(chuàng)新互聯(lián)

成都seo排名網站優(yōu)化
国产精品夜色一区二区三区不卡| 精品裸足人妻少妇二区三区| 日韩欧美亚洲国产另类| 国产一区二区三区不卡视频| 亚洲日本中文字幕免费观看| 永久免费看黄在线观看| 日韩一级黄色片在线播放| 亚洲国产精品二区三区| 亚洲乱色一区二区三区丝袜| 永久免费看黄在线观看| 亚洲中文字幕乱码熟女在线| 欧美久久久久综合一区| av资源在线观看少妇丰满| 免费在线av一区二区| 麻豆精品情欲人妻二区| 中文字幕三级电影天堂| 国内校园性猛交视频网站| 男人的天堂av免费看看| 欧美日韩国产av一区| 美女诱惑丝袜国产国产av丝袜| 国产男女免费完整视频| 97国产精品亚洲精品| 97视频网站在线观看| 中文字幕av在线有码| 日韩三级av黄片在线| 欧美激情另类综合国内| 亚洲国产精品久久久久国产精品| 91国语对白在线观看| av永久免费观看网站| 久久国产精品久久国产精品| 亚洲a∨乱码一区二区三区蜜臀| 中文字幕日韩欧美一区二区| 亚洲永久免费在线观看| 日韩av熟女人妻一区二| 日韩精选视频在线播放| av中文字幕一二三区| 一区二区三区不卡中文字幕| 黄色三级视频一区二区三区| 欧美日韩亚洲精品三级| 国产男生午夜福利网站| 成人在线午夜免费视频|