專利名稱:適用于帶時移iptv直播服務(wù)器的專用磁盤讀寫系統(tǒng)的制作方法
技術(shù)領(lǐng)域:
本發(fā)明屬于網(wǎng)絡(luò)多媒體技術(shù)領(lǐng)域。具體涉及一個適用于帶時移IPTV直播服務(wù)器的專用磁盤讀寫系統(tǒng)以及使用該專用磁盤讀寫系統(tǒng)的帶時移IPTV直播服務(wù)器。
背景技術(shù):
IPTV(Internet Protocol Television)(網(wǎng)絡(luò)電視)利用寬帶網(wǎng)絡(luò)、多媒體、通訊等技術(shù),向機頂盒、PC、手機等用戶終端提供數(shù)字電視等多種交互式服務(wù)。典型的IPTV應(yīng)用包括視頻直播和視頻點播等。在IPTV視頻直播應(yīng)用中,時移(timeshift)是一個非常新穎的功能點。使用帶時移直播服務(wù),用戶不僅可以觀看當(dāng)前時刻的直播內(nèi)容,也可以對前面一段時間的內(nèi)容進行實時類VCR(Video Cassette Recorder)操作,其中包含暫定、拖動、快進、快退等操作。本發(fā)明將提供時移服務(wù)的直播服務(wù)器稱為帶時移直播服務(wù)器。帶時移直播服務(wù)器必須對直播數(shù)據(jù)進行持續(xù)、有效的存儲,并按照用戶的要求從存儲中提取數(shù)據(jù)進行發(fā)送,所以磁盤讀寫策略與性能是其中的一個關(guān)鍵點。
與一般應(yīng)用的磁盤讀寫等特性相比,帶時移直播服務(wù)具有實時性、持續(xù)高流量數(shù)據(jù)I/O、用戶行為連續(xù)等特點。目前通用型的Linux操作系統(tǒng)并不是針對這些特點進行設(shè)計的,在這類應(yīng)用環(huán)境下難以達到好的性能。
發(fā)明內(nèi)容
本發(fā)明的目的在于提供一種適用于帶時移IPTV直播服務(wù)器的專用磁盤讀寫系統(tǒng)。以便有效提高磁盤讀寫效率,從而提升服務(wù)器的整體性能。
Linux系統(tǒng)默認的磁盤讀寫機制不能很好適應(yīng)帶時移直播服務(wù)器的磁盤讀寫的需要,本發(fā)明在使用了異步I/O、DIRECTI/O、tmpfs內(nèi)存文件系統(tǒng)、共享內(nèi)存等技術(shù)為基礎(chǔ),構(gòu)建了一套適用于帶時移IPTV直播服務(wù)器的專用磁盤讀寫系統(tǒng),簡稱直播時移專用磁盤讀寫系統(tǒng)。
本發(fā)明將帶時移IPTV直播服務(wù)器稱為ClearLiveServer。ClearLiveServer中采用本發(fā)明的專用磁盤讀寫系統(tǒng)以提高其整體性能。圖1是ClearLiveServer的整體架構(gòu)示意圖,圖2是采用操作系統(tǒng)默認磁盤讀寫機制的普通帶時移直播服務(wù)器的整體架構(gòu)示意圖。
ClearLiveServer架構(gòu)在詳細說明專用磁盤讀寫系統(tǒng)的功能、結(jié)構(gòu)之前,先對ClearLiveServer系統(tǒng)進行介紹。ClearLiveServer在總體上有四個組成部分
1、媒體數(shù)據(jù)預(yù)處理模塊該模塊用于對從原始直播數(shù)據(jù)源接收到的數(shù)據(jù)進行處理,轉(zhuǎn)換成為適合直播時移應(yīng)用的格式,并通過專用磁盤讀寫系統(tǒng)進行數(shù)據(jù)存儲。同時維護頻道的索引信息,在直播時移專用磁盤讀寫系統(tǒng)中需要用這個索引信息來進行數(shù)據(jù)的定位。
2、媒體數(shù)據(jù)發(fā)送模塊該模塊把直播時移的節(jié)目,通過流媒體的形式發(fā)送到各個客戶端。頻道媒體數(shù)據(jù)通過專用磁盤讀寫系統(tǒng)獲得。
因此,該模塊接收用戶管理模塊布置的客戶端傳輸任務(wù),從專用磁盤讀寫系統(tǒng)獲取頻道媒體數(shù)據(jù)。
3、用戶管理模塊該模塊負責(zé)對用戶進行管理,當(dāng)有新的直播時移用戶加入時,把數(shù)據(jù)傳輸?shù)娜蝿?wù)交給媒體數(shù)據(jù)發(fā)送模塊。
因此,該模塊向媒體數(shù)據(jù)發(fā)送模塊布置客戶端傳輸任務(wù)。
4、直播時移專用磁盤讀寫系統(tǒng)該系統(tǒng)主要的功能有兩點①提供與文件系統(tǒng)類似的功能,但與一般的文件系統(tǒng)面向文件操作不同,直播時移專用磁盤讀寫系統(tǒng)是面向頻道的,上層模塊可以通過它來方便地寫入或者讀出頻道的媒體數(shù)據(jù);②在直播時移專用磁盤讀寫系統(tǒng)中根據(jù)直播時移數(shù)據(jù)存儲和讀取的特點,綜合運用各種技術(shù)進行性能優(yōu)化,能較充分地利用服務(wù)器的磁盤I/O系統(tǒng)和內(nèi)存系統(tǒng),來提升整個流媒體服務(wù)器的能力。
該系統(tǒng)從媒體數(shù)據(jù)預(yù)處理模塊取得數(shù)據(jù),并把數(shù)據(jù)提供給媒體數(shù)據(jù)發(fā)送模塊。
由上可見,直播時移專用磁盤讀寫系統(tǒng)起到了一個關(guān)鍵的數(shù)據(jù)中轉(zhuǎn)的作用,媒體數(shù)據(jù)從預(yù)處理模塊傳到直播時移專用磁盤讀寫系統(tǒng),再從專用磁盤讀寫系統(tǒng)傳給數(shù)據(jù)發(fā)送模塊,并最終發(fā)送到各個客戶端播放器。
直播時移專用磁盤讀寫系統(tǒng)架構(gòu)本發(fā)明提出的專用磁盤讀寫系統(tǒng),采用C/S(客戶端服務(wù)器)架構(gòu),它包含一個媒體數(shù)據(jù)緩存服務(wù)器和若干個緩存客戶端。
緩存客戶端包括兩類直播數(shù)據(jù)寫客戶端和直播數(shù)據(jù)讀客戶端。
1、直播數(shù)據(jù)寫客戶端是專用磁盤讀寫系統(tǒng)中提供給外部模塊進行頻道數(shù)據(jù)寫入操作的接口模塊,通過它來創(chuàng)建一個頻道,并向頻道中寫入數(shù)據(jù)。
該接口模塊連接于媒體數(shù)據(jù)預(yù)處理模塊和媒體數(shù)據(jù)緩存服務(wù)器模塊之間。
2、直播數(shù)據(jù)讀客戶端是專用磁盤讀寫系統(tǒng)中提供給外部模塊進行頻道數(shù)據(jù)讀取操作的接口模塊,通過它來打開已有的頻道,并從頻道中獲取數(shù)據(jù),以提供給媒體數(shù)據(jù)發(fā)送模塊進行數(shù)據(jù)發(fā)送。該接口模塊連接于媒體數(shù)據(jù)發(fā)送模塊和媒體數(shù)據(jù)緩存服務(wù)器模塊之間。
媒體數(shù)據(jù)緩存服務(wù)器分為三個子模塊頻道管理模塊、緩存管理模塊和文件讀寫模塊。
1、頻道管理模塊在系統(tǒng)中,單個頻道的數(shù)據(jù)由若干個數(shù)據(jù)文件組成,同時還有每個數(shù)據(jù)文件對應(yīng)的索引文件,以及可對這些索引文件進行檢索的頻道索引。頻道管理模塊的作用是接收客戶端的請求,通過一系列的索引,把用戶請求的數(shù)據(jù)定位到具體的數(shù)據(jù)文件中,再通過調(diào)用緩存管理模塊提供的接口,進行數(shù)據(jù)塊的處理。
模塊間關(guān)系接收緩存客戶端的請求,調(diào)用緩存管理模塊的接口來獲取或者寫入數(shù)據(jù)塊。頻道索引由媒體數(shù)據(jù)預(yù)處理模塊進行維護。
2、緩存管理模塊系統(tǒng)中的媒體數(shù)據(jù)文件按照數(shù)據(jù)塊的形式來組織,對媒體數(shù)據(jù)文件的讀取和寫入也都是以數(shù)據(jù)塊為單位進行,塊狀數(shù)據(jù)處理可以盡量減小I/O操作。緩存塊是在系統(tǒng)內(nèi)存中分配,每個緩存塊都可以存放一個數(shù)據(jù)塊。
緩存塊管理模塊的作用是維護所有的緩存塊,為媒體數(shù)據(jù)文件中的數(shù)據(jù)塊分配緩存塊,被分配到緩存塊的數(shù)據(jù)塊,在以后的訪問中,可以直接使用在內(nèi)存中的數(shù)據(jù),不需要訪問硬盤。由于物理內(nèi)存容量有限,媒體文件中的數(shù)據(jù)塊只有一部分可以被分配到,當(dāng)需要存放新的數(shù)據(jù)塊時,緩存塊管理模塊會在當(dāng)前的緩存池中選出最不可能被使用到的數(shù)據(jù)塊,把它占有的緩沖塊釋放出來,用于存放新的數(shù)據(jù)塊。
模塊間關(guān)系頻道管理模塊通過調(diào)用緩存管理模塊的接口,來向媒體數(shù)據(jù)文件中寫入數(shù)據(jù)塊或從媒體數(shù)據(jù)文件中讀取數(shù)據(jù)塊;緩存管理模塊會向文件讀寫模塊發(fā)起數(shù)據(jù)塊的讀寫請求,由文件讀寫模塊把文件中的數(shù)據(jù)塊讀取并放到緩存塊中,或者把緩存塊中的數(shù)據(jù)寫入到實際的文件中。
采用的技術(shù)使用基于tmpfs和內(nèi)存文件映射的內(nèi)存在緩存塊管理模塊中,緩存塊不像一般的程序通過malloc等類似調(diào)用來獲得,而是通過Linux系統(tǒng)中的tmpfs文件系統(tǒng)以及內(nèi)存文件映射機制來實現(xiàn)。在考慮下面幾點要求的前提下,結(jié)合tmpfs文件系統(tǒng)和內(nèi)存文件映射來表示緩存塊①緩存塊管理需要大量的內(nèi)存,來達到較高的緩沖命中率。
②緩存塊需要可以高效地在不同模塊之間共享。
③在通常的32位系統(tǒng)上,進程的可用地址空間是2GB,而商用服務(wù)器的內(nèi)存可以超過這個數(shù)目,需要有效使用系統(tǒng)的內(nèi)存。
tmpfs是基于系統(tǒng)內(nèi)存的文件系統(tǒng),也就是說在tmpfs下的文件實際上都存放在系統(tǒng)內(nèi)存中。而且tmpfs可以充分利用服務(wù)器的內(nèi)存資源,不會有2GB的限制。再加上內(nèi)存文件映射技術(shù),可使得1,在不同的模塊間,通過對在tmpfs中的同一個文件的映射,就可以實現(xiàn)數(shù)據(jù)的共享;2內(nèi)存文件映射是動態(tài)的,可以隨時建立和撤銷,既可以使用到巨大的系統(tǒng)內(nèi)存,又不會造成進程的地址空間不足。
ii、緩存管理緩存管理主要是為有價值(被多次使用的可能性大)的數(shù)據(jù)塊分配緩存塊,從另一個方面也就是要把緩存塊從最沒價值(對多次使用的可能性小)的數(shù)據(jù)塊中釋放出來。在為新的數(shù)據(jù)塊分配緩存塊時,如果緩存塊不足,就需要用數(shù)據(jù)塊淘汰算法選擇出一塊最不可能會被使用到的數(shù)據(jù)塊,把它占用的緩存塊釋放出來,用來存放新的數(shù)據(jù)塊。淘汰算法要選擇最晚被用到的數(shù)據(jù)塊。用流來表示某個用戶觀看直播時移時候的狀態(tài),主要關(guān)注當(dāng)前使用的數(shù)據(jù)塊在媒體文件中所處的位置。在正常播放狀態(tài)下,媒體流獲取數(shù)據(jù)的順序是依次往后,數(shù)據(jù)塊的下次訪問時間可以用它與前面鄰近的流之間的距離來表示,距離越遠就越晚會被用到。為了較快地找出最晚被使用到的數(shù)據(jù)塊,先找出單個媒體文件中最晚訪問的數(shù)據(jù)塊,再從所有這樣的數(shù)據(jù)塊中選出最終的最晚訪問的數(shù)據(jù)塊。同時注意到夾在兩個流之間的數(shù)據(jù)塊,最靠后面的數(shù)據(jù)塊必然比前面的要晚訪問,所以只要比較每個相鄰流之間最靠后的數(shù)據(jù)塊就可以了。
3、文件讀寫模塊文件讀寫模塊的作用是接收上層發(fā)起的數(shù)據(jù)塊讀寫請求,把數(shù)據(jù)塊從文件中讀出,放到緩存塊中,或者把數(shù)據(jù)塊的內(nèi)容從緩存塊中寫入到文件。
模塊間關(guān)系被緩存管理模塊調(diào)用,進行實際的媒體數(shù)據(jù)文件的數(shù)據(jù)塊讀寫。與緩存管理模塊在不同的線程中運行。
采用的技術(shù)在文件讀寫模塊中,采用兩個技術(shù)DIRECT I/O和異步I/O。
i、DIRECT方式的磁盤I/O繞過了系統(tǒng)的文件系統(tǒng)緩存,把文件讀寫請求直接交給磁盤,這可以避免在使用Linux下默認的文件系統(tǒng)緩存機制時,對流媒體系統(tǒng)的服務(wù)質(zhì)量造成的影響。在使用文件緩存時,Linux會盡量地使用內(nèi)存作為緩存,來達到通用情況下較好的磁盤吞吐性能,但是這有兩點地方會對流媒體系統(tǒng)的服務(wù)質(zhì)量造成影響1,只有當(dāng)緩存中的臟數(shù)據(jù)較多時,才會發(fā)起大量寫請求,把數(shù)據(jù)刷新到實際的磁盤文件中,這樣的寫操作帶有很強的突發(fā)性,會在這段時間內(nèi)占用大量的系統(tǒng)資源,從而對別的應(yīng)用造成影響,特別是對流媒體服務(wù)這樣時間敏感的應(yīng)用,會使得短時間內(nèi)數(shù)據(jù)處理能力不足,影響服務(wù)質(zhì)量;2,流媒體應(yīng)用中的磁盤讀寫規(guī)律有著其自身的特點,默認的文件系統(tǒng)緩存是針對一般的用途,因而不能達到最好的效果。通過DIRECT I/O,我們可以構(gòu)造自己的適合流媒體應(yīng)用的緩存機制,提高服務(wù)器的性能。
ii、異步I/O的主要特征就是操作請求的發(fā)起和操作結(jié)果的獲得是分開的。主要優(yōu)點有數(shù)據(jù)處理和I/O操作重疊進行,有利于提高CPU的使用率;在同步IO中,只有一個請求完成了以后,才能進行下一次請求,磁盤的性能不能很好表現(xiàn)出來,而通過異步I/O可以使得磁盤設(shè)備的請求管道中總是保持一定量的請求,有利于提高其利用率。把異步I/O與DIRECT I/O的直接把讀寫請求發(fā)送給磁盤設(shè)備的特點相結(jié)合,我們通過控制發(fā)送請求的頻率來控制磁盤的吞吐量,使磁盤系統(tǒng)對整個流媒體系統(tǒng)的影響保持在一個較低的水平。
處理流程在介紹完直播時移專用磁盤讀寫系統(tǒng)的架構(gòu)、組成后,我們再用動態(tài)的流程來描述系統(tǒng)運行時的狀況。下面按照媒體數(shù)據(jù)的接收和發(fā)送兩條線索分別進行描述。
當(dāng)媒體數(shù)據(jù)被接收時,ClearLiveServer中的各個模塊會進行下面這些流程的處理(如圖3)(1)媒體數(shù)據(jù)預(yù)處理模塊a)從原始數(shù)據(jù)源接收直播數(shù)據(jù);b)把數(shù)據(jù)進行處理,如判斷是否是關(guān)鍵幀,記錄接收時間等;c)把數(shù)據(jù)放到從媒體數(shù)據(jù)緩存服務(wù)器得到的緩沖塊隊列的隊頭緩沖塊中(緩沖塊用于存放最新接收的數(shù)據(jù),隊列中有若干個緩沖塊);d)如果隊頭緩沖塊數(shù)據(jù)已經(jīng)滿了,通過直播數(shù)據(jù)寫客戶端向媒體數(shù)據(jù)緩存服務(wù)器寫入最新的數(shù)據(jù)塊,然后調(diào)整緩沖塊隊列-把隊頭緩沖塊移到隊尾(緩存塊隊列是循環(huán)使用的);e)更新頻道的索引。
(2)媒體數(shù)據(jù)緩存服務(wù)器模塊a)最新的數(shù)據(jù)往往最可能被用戶需要,所以頻道管理模塊從緩存管理模塊中取得一塊空閑的緩存塊,把它分配給最新的數(shù)據(jù)塊,并且直接把當(dāng)前最新緩沖塊(在媒體數(shù)據(jù)預(yù)處理模塊和媒體數(shù)據(jù)緩存服務(wù)器模塊之間共享)的內(nèi)容復(fù)制到這個緩存塊中;b)為了把新數(shù)據(jù)塊寫到磁盤文件中,對文件讀寫模塊發(fā)起寫請求;c)文件讀寫模塊從寫請求隊列中獲取一定數(shù)量的請求,并用異步的方式向操作系統(tǒng)遞交寫請求;d)文件讀寫模塊等待異步操作完成。
當(dāng)媒體數(shù)據(jù)被發(fā)送到客戶端時,ClearLiveServer中的各個模塊會進行下面這些流程的處理(如圖4)(1)媒體數(shù)據(jù)發(fā)送模塊a)當(dāng)前流的數(shù)據(jù)塊中的數(shù)據(jù)是否已經(jīng)被發(fā)送完畢,如果是的話,通過直播數(shù)據(jù)讀客戶端向媒體數(shù)據(jù)媒體數(shù)據(jù)緩存服務(wù)器請求數(shù)據(jù)b)把當(dāng)前流數(shù)據(jù)塊中的數(shù)據(jù)按照發(fā)送計劃發(fā)送到客戶端。
(2)媒體數(shù)據(jù)緩存服務(wù)器模塊常規(guī)的數(shù)據(jù)獲取流程a)頻道管理模塊根據(jù)頻道索引,計算出請求的數(shù)據(jù)所在的媒體文件以及偏移位置,向緩存管理模塊請求數(shù)據(jù)。
b)緩存管理模塊檢查對于的數(shù)據(jù)塊是否在緩存中。如果不在緩存中,則通過數(shù)據(jù)塊淘汰算法,得到一個空閑的緩存塊,分配給請求的的數(shù)據(jù)塊,并向文件讀寫模塊發(fā)起讀請求。
c)文件讀寫模塊從讀請求隊列中獲取一定數(shù)量的請求,并用異步的方式向操作系統(tǒng)遞交讀請求。
d)文件讀寫模塊等待異步操作完成,并標(biāo)記完成讀取的緩存塊的可用位,以表示緩存塊中已經(jīng)包含有效數(shù)據(jù),可以被其他模塊使用。
數(shù)據(jù)預(yù)讀流程除了上面說明的對數(shù)據(jù)獲取請求的處理外,為了進一步提高緩存的命中率,我們根據(jù)流媒體數(shù)據(jù)讀取的特點,進行了數(shù)據(jù)預(yù)讀的處理。處理流程和常規(guī)的數(shù)據(jù)獲取流程基本一樣,只在前面多了一步對預(yù)讀數(shù)據(jù)塊的預(yù)測。
a)判斷下一個可能被讀取的數(shù)據(jù)塊(根據(jù)不同情況,可能是前面常規(guī)流程中請求數(shù)據(jù)塊的下一塊,也可能是上一塊);b)頻道管理模塊根據(jù)頻道索引,計算出請求的數(shù)據(jù)塊所在的媒體文件以及偏移位置,向緩存管理模塊請求數(shù)據(jù);c)緩存管理模塊檢查對于的數(shù)據(jù)塊是否在緩存中。如果不在緩存中,則通過數(shù)據(jù)塊淘汰算法,得到一個空閑的緩存塊,分配給請求的的數(shù)據(jù)塊,并向文件讀寫模塊發(fā)起讀請求;d)文件讀寫模塊從讀請求隊列中獲取一定數(shù)量的請求,并用異步的方式向操作系統(tǒng)遞交讀請求;
e)文件讀寫模塊等待異步操作完成,并標(biāo)記完成讀取的緩存塊的可用位,以表示緩存塊中已經(jīng)包含有效數(shù)據(jù),可以被其他模塊使用。
圖1是采用了專業(yè)磁盤讀寫系統(tǒng)的ClearLiveServer的整體架構(gòu)示意圖。
圖2是采用操作系統(tǒng)默認磁盤讀寫機制的普通帶時移直播服務(wù)器的整體架構(gòu)示意圖。
圖3是媒體數(shù)據(jù)接收時系統(tǒng)主要流程圖。
圖4是媒體數(shù)據(jù)發(fā)送時系統(tǒng)主要流程圖。
圖中標(biāo)號1為用戶管理模塊,2為媒體數(shù)據(jù)預(yù)處理模塊,3為媒體數(shù)據(jù)發(fā)送模塊,4為直播數(shù)據(jù)寫客戶端,5為直播數(shù)據(jù)讀客戶端,6為頻道管理模塊,7為緩沖管理模塊,8為文件讀寫模塊,9為直播時移專用磁盤讀寫系統(tǒng),10為媒體數(shù)據(jù)緩存服務(wù)器,11為存儲介質(zhì),12為用戶,13為操作系統(tǒng)默認I/O模塊。
具體實施例方式
下面對本發(fā)明的具體實施和進一步描述。
基本數(shù)據(jù)結(jié)構(gòu)在Linux系統(tǒng)下,默認的tmpfs內(nèi)存文件系統(tǒng)被掛載在/dev/shm下,因此系統(tǒng)中的緩存塊也存放在/dev/shm下。直播時移專用磁盤讀寫系統(tǒng)初始化時,會在/dev/shm下面創(chuàng)建一系列文件,文件的大小都一致,每一個文件都代表了一個緩存塊。緩存塊在系統(tǒng)中用結(jié)構(gòu)體CachedBlock來表示struct CachedBlock{char block_data[CACHED_BLOCK_SIZE];int state;}緩存塊包括了數(shù)據(jù)塊block_data和標(biāo)志位state,在用于讀取數(shù)據(jù)塊時,標(biāo)記位state用DATA_READY和DATA_NREADY來分別表示block_data中是否已經(jīng)包含有效數(shù)據(jù)。
為了方便管理我們還使用了一個控制塊的結(jié)構(gòu),用來描述緩存塊和/dev/shm下內(nèi)存文件的關(guān)系struct ManagedBlock{char block_file[PATH_MAX];int fd;CachedBlock*cached_block;}其中block_file表示了在/dev/shm中的內(nèi)存文件的文件名,fd是這個文件的描述符,cached_block是通過文件內(nèi)存映射過來的緩存塊,由于進程的虛存空間有限,只有在需要的時候才進行緩存塊的映射。映射的方法為managed_block->cached_block=(CachedBlock*)mmap(NULL,sizeof(CachedBlock),PROT_READ|PROT_WRITE,MAP_SHARED,managed_block->fd,0);解除映射的方法為munmap(managed_block->cached_block,sizeof(CachedBlock))。通過在不同模塊間對相同的內(nèi)存文件進行映射,就可實現(xiàn)進程間緩存塊的共享。
直播數(shù)據(jù)讀客戶端直播數(shù)據(jù)讀客戶端用ChannelReadFile來表示,在媒體數(shù)據(jù)發(fā)送模塊每個播放的流都擁有一個ChannelReadFile,通過ChannelReadFile從媒體數(shù)據(jù)媒體數(shù)據(jù)緩存服務(wù)器獲取數(shù)據(jù)。
ChannelReadFile有如下的一些方法bool open(char*channel);//打開頻道bool close();//關(guān)閉頻道CachedBlock*getBlockByTime(uint64 time);//取得某個時間點的數(shù)據(jù)CachedBlock*getPreBlock();//取得上一塊數(shù)據(jù)CachedBlock*getNextBlock();//取得下一塊數(shù)據(jù)CachedBlock*getOldestBlock();//取得最老的數(shù)據(jù)ChannelReadFile和媒體數(shù)據(jù)緩存服務(wù)器之間通過Unix Domain Socket進行通信,UnixDomain Socket類似與一般的網(wǎng)絡(luò)套接字,但它專門用于進程間通信,效率很高。ChannelReadFile向媒體數(shù)據(jù)媒體數(shù)據(jù)緩存服務(wù)器模塊發(fā)送請求,根據(jù)請求的結(jié)果來完成具體的功能,其中后面四個取數(shù)據(jù)塊的操作都是從緩沖服務(wù)器得到包含所請求的數(shù)據(jù)的緩存塊的文件名,并把這個內(nèi)存文件映射到進程地址空間中。
通過ChannelReadFile來獲取數(shù)據(jù)是先得到一個CacheBlock結(jié)構(gòu),再通過監(jiān)測其中的標(biāo)記位來判斷數(shù)據(jù)塊是否可用,這使得當(dāng)某些流的數(shù)據(jù)還沒準(zhǔn)備好的時候,還可以進行別的數(shù)據(jù)流的數(shù)據(jù)發(fā)送工作,而不至于一直等待某個流的數(shù)據(jù)到達,而耽誤別的流的發(fā)送,這樣就提高了系統(tǒng)的服務(wù)質(zhì)量,不同流之間的互相干擾盡量減小。
直播數(shù)據(jù)寫客戶端直播數(shù)據(jù)寫客戶端用ChannelWriteFile來表示,每個頻道都有一個ChannlWriteFile,通過ChannelWriteFile向媒體數(shù)據(jù)緩存服務(wù)器寫入媒體數(shù)據(jù)。ChannelWiteFile與媒體數(shù)據(jù)緩存服務(wù)器之間也是使用Unix Domain Socket進行通信。
ChannelWriteFile有如下一些方法ChannelIndex*open(char*channel name);//創(chuàng)建一個頻道
CachedBlock**getBuffer(int size);//獲得一組緩存數(shù)據(jù)塊bool close();//關(guān)閉一個頻道bool putBlock();//把最新數(shù)據(jù)塊的內(nèi)容寫到磁盤上用open方法成功創(chuàng)建一個頻道后,會得到一個與媒體數(shù)據(jù)緩存模塊之間共享的頻道索引結(jié)構(gòu),這個頻道的索引由媒體數(shù)據(jù)預(yù)處理模塊進行維護,而媒體數(shù)據(jù)緩存服務(wù)器利用它來進行數(shù)據(jù)塊的查找。
由于時移節(jié)目存儲的媒體數(shù)據(jù)很龐大,單個文件無法容納,在系統(tǒng)中一個頻道由一組媒體數(shù)據(jù)文件來表示,此外為了管理這些數(shù)據(jù)文件,還引入了索引,索引分為兩層,每個媒體文件有自己的索引,又有一個關(guān)于這一級索引的頻道總索引。索引信息由媒體數(shù)據(jù)接收模塊維護。
每個媒體文件索引為struct ChannelSegmentIndex{int block_count;//塊的數(shù)量uint64 start_time;//文件中最舊數(shù)據(jù)的時間uint64 end_time;//文件中最新數(shù)據(jù)的時間ChannelBlockIndex blocks[BLOCK_COUNT_MAX];//數(shù)據(jù)塊的索引}其中每個數(shù)據(jù)塊的索引為struct ChannelBlockIndex{uint64 start_time;//數(shù)據(jù)塊中最舊數(shù)據(jù)的時間uint64 end_time;//數(shù)據(jù)塊中最新數(shù)據(jù)的時間}每個頻道的總索引為struct ChannelIndex{uint64 start_time;//頻道中最舊數(shù)據(jù)的時間uint64 end_time;//頻道中最新數(shù)據(jù)的時間int first_segment_offset;//第一個媒體文件索引在下面數(shù)組中的偏移量int segment_count;//媒體文件的個數(shù)ChannelSegmentSimpleIndex segments[SEGMENT_COUNT_MAX];//縮略的媒體文件索引}ChannelSegmentSimpleIndex表示了媒體文件的一些簡單信息
struct ChannelSegmentSimpleIndex{char index_file[PATH_MAX];//媒體索引文件名char data_file[PATH_MAX];//媒體數(shù)據(jù)文件名uint64 start_time;//文件中最舊數(shù)據(jù)的時間uint64 end_time;//文件中最舊數(shù)據(jù)的時間int block_count;//文件中的數(shù)據(jù)塊數(shù)目}利用上面的這些索引信息,可以對某個時間點的數(shù)據(jù)進行定位,也可以對相對位置進行定位,如當(dāng)前位置的后一塊數(shù)據(jù)或前一塊數(shù)據(jù)等。
需要接收數(shù)據(jù)時,用getBuffer方法來獲得一批存放媒體數(shù)據(jù)的緩沖區(qū)數(shù)據(jù)塊,當(dāng)最新的緩沖區(qū)數(shù)據(jù)塊被填滿后,使用putBlock方法向媒體數(shù)據(jù)緩存模塊申請把數(shù)據(jù)寫入到磁盤上,然后把最老的緩沖區(qū)數(shù)據(jù)塊作為數(shù)據(jù)接收使用的數(shù)據(jù)塊,也就是說依次循環(huán)使用這批緩沖區(qū)數(shù)據(jù)塊。在把數(shù)據(jù)填充到數(shù)據(jù)塊中后,還需要陸續(xù)修改頻道索引結(jié)構(gòu)中的各個字段,使數(shù)據(jù)內(nèi)容和索引結(jié)構(gòu)保持一致,修改的選擇是從小到大、從下到上,即按ChannelBlockIndex、ChannelSegmentIndex、ChannelSegmentSimpleIndex、ChannelIndex的次序進行了修改。由于在媒體數(shù)據(jù)緩存服務(wù)器中,對索引的查找是按從大到小、從上到下的次序,即ChannelIndex、ChannelSegmentSimpleIndex、ChannelSegmentIndex、ChannelBlockIndex,上面修改次序可以保證上層的索引總是反映了下層的實際情況,從而使得檢索正確進行。
媒體數(shù)據(jù)媒體數(shù)據(jù)緩存服務(wù)器媒體數(shù)據(jù)媒體數(shù)據(jù)緩存服務(wù)器是專用磁盤讀寫系統(tǒng)的核心,管理所有的緩存塊,處理來自媒體數(shù)據(jù)接收模塊和媒體數(shù)據(jù)發(fā)送模塊的各種請求。
頻道管理模塊和緩存管理模塊在媒體數(shù)據(jù)媒體數(shù)據(jù)緩存服務(wù)器中,每個媒體文件都用結(jié)構(gòu)體Movie來表示struct Movie{char file_name[PATH_MAX];int fd;ManagedBlock*blocks[BLOCK_MAX];int block_count;Stream*first_stream;Stream*last_stream;}
file_name表示了媒體文件的路徑,fd是對應(yīng)的文件描述符,blocks是對文件中數(shù)據(jù)塊的簡單索引,如果數(shù)據(jù)塊被分配了緩存塊,則在blocks數(shù)組中對應(yīng)的管理塊就非空,block_count表示媒體文件中包含的數(shù)據(jù)塊的數(shù)量,first_stream和last_stream分別表示了當(dāng)前的數(shù)據(jù)請求位置在這個媒體數(shù)據(jù)文件中的第一個數(shù)據(jù)流和最后一個數(shù)據(jù)流。打開媒體文件的時候,我們使用了movie->fd=open(movie->file_name,O_RDWR|O_LARGEFILE|O_DIRECT)的方式,其中O_LARGEFILE表示支持超過4G的大文件(因為媒體文件可能很大),O_DIRECT表示對此文件的操作最大程度上繞過系統(tǒng)的緩存機制,這使得我們在上層構(gòu)建特殊的緩存機制成為可能。
我們用結(jié)構(gòu)體stream來表示流struct Stream{int block_id;Stream*pre_stream;Stream*next_stream;}block_id表示了流在媒體數(shù)據(jù)文件中所處位置,pre_stream指向相鄰的位置靠前的流,而next_stream指向相鄰的位置靠后的流。
通過Movie結(jié)構(gòu)體中的信息,可以得出當(dāng)前緩存塊的分配情況,從而應(yīng)用前面提到的數(shù)據(jù)塊淘汰算法釋放緩存塊,來把這個緩存塊分配給更有價值的數(shù)據(jù)塊。
媒體數(shù)據(jù)緩存服務(wù)器在接受到頻道數(shù)據(jù)讀客戶端的數(shù)據(jù)請求時,除了根據(jù)客戶端實際的數(shù)據(jù)請求提供數(shù)據(jù)外,還需要根據(jù)客戶端的行為預(yù)測它后面可能會讀取的數(shù)據(jù)。數(shù)據(jù)預(yù)讀處理中的預(yù)測如下1.如果是getBlockByTime、getOldestBlock或者getNextBlock請求,需要預(yù)取當(dāng)前所需的數(shù)據(jù)塊的后一個鄰近數(shù)據(jù)塊。
2.如果是getPreBlock請求,需要預(yù)取當(dāng)前所需的數(shù)據(jù)塊的前一個鄰近數(shù)據(jù)塊。
文件讀寫模塊文件讀寫模塊實際上可以分成文件讀模塊和文件寫模塊,并且運行在兩個單獨的線程中。
文件讀模塊文件讀模塊對外提供的接口用來添加一個異步讀的請求addReadRequest(int file_fd,intblock_id,CachedBlock*store)。在模塊內(nèi)部維護了一個讀請求的隊列,在需要時才對請求進行處理。file_fd表示需要讀取的文件的描述符,block_id表示從0開始的數(shù)據(jù)塊序號,store表示需要讀取后的數(shù)據(jù)存放的緩存塊。CachedBlock中的block_data表示了實際數(shù)據(jù)存放的地方,而state是個標(biāo)記位,用來表示數(shù)據(jù)是否已經(jīng)被放入了block_data緩沖區(qū),分別用DATA_READY,DATA_NREADY來表示數(shù)據(jù)已經(jīng)讀入和數(shù)據(jù)未被讀入。
在Linux的異步I/O操作中,需要用到下面一些結(jié)構(gòu)結(jié)構(gòu)體aio_context_t是Linux系統(tǒng)異步I/O中異步操作的上下文,結(jié)構(gòu)體struct iocb表示異步操作的請求塊。
前面已經(jīng)描述過了對于讀請求的處理流程(圖4),下面進一步用實際程序中的過程進行描述1、從讀請求隊列中獲取一定量的請求,新獲取請求的數(shù)目加上遞交的但未完成請求的數(shù)目不能大于A_READ_MAX,這保證了不會對磁盤造成太大壓力,有利于系統(tǒng)穩(wěn)定,目前系統(tǒng)中A_READ_MAX為10。對每個新請求都進行下面兩步操作a)借助io_prep_pread把addReadRequest中的異步讀請求轉(zhuǎn)換為系統(tǒng)需要的請求塊形式,如io_prep_pread(io,file_fd,store,CACHED_BLOCK_SIZE,CACHED_BLOCK_SIZE*block_id),表示了把文件file_fd中偏移量為CACHED_BLOCK_SIZE*block_id字節(jié)處的CACHED_BLOCK_SIZE字節(jié)的數(shù)據(jù)讀取到store指向的緩沖區(qū)中,而這個請求用io這個請求塊來表示。
b)通過io_submit向操作系統(tǒng)遞交異步I/O請求,如io_submit(io_context,1,&io)。
2、用io_getevents來等待異步操作的完成,當(dāng)成功完成后,把對應(yīng)的CachedBlock的state標(biāo)記置成DATA_READY。
文件寫模塊異步模式文件寫模塊和讀模塊的處理流程類似(圖3),除了準(zhǔn)備異步請求塊時用io_prep_pwrite,當(dāng)異步操作完成時,不需要進行別的處理。
權(quán)利要求
1.一種適用于時移IPTV直播服務(wù)器的專用磁盤讀寫系統(tǒng),其特征在于它包含一個媒體數(shù)據(jù)緩存服務(wù)器和若干個緩存客戶端;其中,緩存客戶端包括直播數(shù)據(jù)寫客戶端和直播數(shù)據(jù)讀客戶端(1)直播數(shù)據(jù)寫客戶端是專用磁盤讀寫系統(tǒng)中提供給外部模塊進行頻道數(shù)據(jù)寫入操作的接口模塊,通過它來創(chuàng)建一個頻道,并向頻道中寫入數(shù)據(jù);該接口模塊連接于媒體數(shù)據(jù)預(yù)處理模塊和媒體數(shù)據(jù)緩存服務(wù)器模塊之間;(2)直播數(shù)據(jù)讀客戶端是專用磁盤讀寫系統(tǒng)中提供給外部模塊進行頻道數(shù)據(jù)讀取操作的接口模塊,通過它來打開已有的頻道,并從頻道中獲取數(shù)據(jù),以提供給媒體數(shù)據(jù)發(fā)送模塊進行數(shù)據(jù)發(fā)送;該接口模塊連接于媒體數(shù)據(jù)發(fā)送模塊和媒體數(shù)據(jù)緩存服務(wù)器模塊之間;媒體數(shù)據(jù)緩存服務(wù)器分為三個子模塊頻道管理模塊、緩存管理模塊和文件讀寫模塊(1)頻道管理模塊頻道管理模塊的作用是接收客戶端的請求,通過一系列的索引,把用戶請求的數(shù)據(jù)定位到具體的數(shù)據(jù)文件中,再通過調(diào)用緩存管理模塊提供的接口,進行數(shù)據(jù)塊的處理;模塊間關(guān)系接收緩存客戶端的請求,調(diào)用緩存管理模塊的接口來獲取或者寫入數(shù)據(jù)塊;頻道索引由媒體數(shù)據(jù)預(yù)處理模塊進行維護;(2)緩存管理模塊系統(tǒng)中的媒體數(shù)據(jù)文件按照數(shù)據(jù)塊的形式來組織,對媒體數(shù)據(jù)文件的讀取和寫入也都以數(shù)據(jù)塊為單位進行,緩存塊在系統(tǒng)內(nèi)存中分配,每個緩存塊都可以存放一個數(shù)據(jù)塊;緩存塊管理模塊的作用是維護所有的緩存塊,為媒體數(shù)據(jù)文件中的數(shù)據(jù)塊分配緩存塊,被分配到緩存塊的數(shù)據(jù)塊,在以后的訪問中,可以直接使用在內(nèi)存中的數(shù)據(jù);模塊間關(guān)系頻道管理模塊通過調(diào)用緩存管理模塊的接口,來向媒體數(shù)據(jù)文件中寫入數(shù)據(jù)塊或從媒體數(shù)據(jù)文件中讀取數(shù)據(jù)塊;緩存管理模塊會向文件讀寫模塊發(fā)起數(shù)據(jù)塊的讀寫請求,由文件讀寫模塊把文件中的數(shù)據(jù)塊讀取并放到緩存塊中,或者把緩存塊中的數(shù)據(jù)寫入到實際的文件中;(3)文件讀寫模塊文件讀寫模塊的作用是接收上層發(fā)起的數(shù)據(jù)塊讀寫請求,把數(shù)據(jù)塊從文件中讀出,放到緩存塊中,或者把數(shù)據(jù)塊的內(nèi)容從緩存塊中寫入到文件;模塊間關(guān)系被緩存管理模塊調(diào)用,進行實際的媒體數(shù)據(jù)文件的數(shù)據(jù)塊讀寫。與緩存管理模塊在不同的線程中運行。
2.根據(jù)權(quán)利要求1所述的適用于時移IPTV直播服務(wù)器的專用磁盤讀寫系統(tǒng),其特征在于所述緩存管理模塊使用基于tmpfs和內(nèi)存文件映射的內(nèi)存;緩存管理模塊在為新的數(shù)據(jù)塊分配緩存時,如果緩存塊不足,則通過一數(shù)據(jù)塊淘汰算法,選擇出一塊最不可能被使用的數(shù)據(jù)塊,把它占用的緩存塊釋放出來,用來存放新的數(shù)據(jù)塊。
3.根據(jù)權(quán)利要求1所述的適用于時移IPTV直播服務(wù)器的專用磁盤讀寫系統(tǒng),其特征在于所述的文件讀寫模塊采用DIRECT I/O和異步I/O。
4.一種使用如權(quán)利要求1所述的專用磁盤讀寫系統(tǒng)的時移IPTV直播服務(wù)器,其特征在于該直播服務(wù)器還包括媒體數(shù)據(jù)預(yù)處理模塊、媒體數(shù)據(jù)發(fā)送模塊和用戶管理模塊,其中(1)媒體數(shù)據(jù)預(yù)處理模塊該模塊用于對從原始直播數(shù)據(jù)源接收到的數(shù)據(jù)進行處理,轉(zhuǎn)換成為適合直播時移應(yīng)用的格式,并通過專用磁盤讀寫系統(tǒng)進行數(shù)據(jù)存儲;同時維護頻道的索引信息,在直播時移專用磁盤讀寫系統(tǒng)中需要用這個索引信息來進行數(shù)據(jù)的定位;(2)媒體數(shù)據(jù)發(fā)送模塊該模塊把直播時移的節(jié)目,通過流媒體的形式發(fā)送到各個客戶端;頻道媒體數(shù)據(jù)通過專用磁盤讀寫系統(tǒng)獲得;(3)用戶管理模塊該模塊負責(zé)對用戶進行管理,當(dāng)有新的直播時移用戶加入時,把數(shù)據(jù)傳輸?shù)娜蝿?wù)交給媒體數(shù)據(jù)發(fā)送模塊。
5.一種如權(quán)利要求4所述的時移IPTV直播服務(wù)器的處理流程,其特征在于具體步驟如下當(dāng)媒體數(shù)據(jù)被接收時,IPTV直播服務(wù)器中的各個模塊進行如下些流程的處理(1)媒體數(shù)據(jù)預(yù)處理模塊a)從原始數(shù)據(jù)源接收直播數(shù)據(jù);b)把數(shù)據(jù)進行處理如判斷是否是關(guān)鍵幀,記錄接收時間;c)把數(shù)據(jù)放到從媒體數(shù)據(jù)緩存服務(wù)器得到的緩沖塊隊列的隊頭緩沖塊中;d)如果隊頭緩沖塊數(shù)據(jù)已經(jīng)滿了,通過直播數(shù)據(jù)寫客戶端向媒體數(shù)據(jù)緩存服務(wù)器寫入最新的數(shù)據(jù)塊,然后調(diào)整緩沖塊隊列—把隊頭緩沖塊移到隊尾;e)更新頻道的索引;(2)媒體數(shù)據(jù)緩存服務(wù)器模塊a)頻道管理模塊從緩存管理模塊中取得一塊空閑的緩存塊,把它分配給最新的數(shù)據(jù)塊,并且直接把當(dāng)前最新緩沖塊的內(nèi)容復(fù)制到這個緩存塊中;b)為了把新數(shù)據(jù)塊寫到磁盤文件中,對文件讀寫模塊發(fā)起寫請求;c)文件讀寫模塊從寫請求隊列中獲取一定數(shù)量的請求,并用異步的方式向操作系統(tǒng)遞交寫請求;d)文件讀寫模塊等待異步操作完成;當(dāng)媒體數(shù)據(jù)被發(fā)送到客戶端時,IPTV直播服務(wù)器中的各個模塊會如下流程的處理(1)媒體數(shù)據(jù)發(fā)送模塊a)當(dāng)前流的數(shù)據(jù)塊中的數(shù)據(jù)是否已經(jīng)被發(fā)送完畢,如果是的話,通過直播數(shù)據(jù)讀客戶端向媒體數(shù)據(jù)媒體數(shù)據(jù)緩存服務(wù)器請求數(shù)據(jù);b)把當(dāng)前流數(shù)據(jù)塊中的數(shù)據(jù)按照發(fā)送計劃發(fā)送到客戶端;(2)媒體數(shù)據(jù)緩存服務(wù)器模塊常規(guī)的數(shù)據(jù)獲取流程a)頻道管理模塊根據(jù)頻道索引,計算出請求的數(shù)據(jù)所在的媒體文件以及偏移位置,向緩存管理模塊請求數(shù)據(jù),b)緩存管理模塊檢查對于的數(shù)據(jù)塊是否在緩存中,如果不在緩存中,則通過數(shù)據(jù)塊淘汰算法,得到一個空閑的緩存塊,分配給請求的的數(shù)據(jù)塊,并向文件讀寫模塊發(fā)起讀請求;c)文件讀寫模塊從讀請求隊列中獲取一定數(shù)量的請求,并用異步的方式向操作系統(tǒng)遞交讀請求;d)文件讀寫模塊等待異步操作完成,并標(biāo)記完成讀取的緩存塊的可用位,以表示緩存塊中已經(jīng)包含有效數(shù)據(jù),可以被其他模塊使用。
6.根據(jù)權(quán)利要求5所述的時移IPTV直播服務(wù)器的處理流程,其特征在于在所述頻道管理模塊中,常規(guī)的數(shù)據(jù)獲取流程步驟之前有一對預(yù)讀數(shù)據(jù)塊的預(yù)讀流程a)判斷下一個可能被讀取的數(shù)據(jù)塊;b)頻道管理模塊根據(jù)頻道索引,計算出請求的數(shù)據(jù)塊所在的媒體文件以及偏移位置,向緩存管理模塊請求數(shù)據(jù);c)緩存管理模塊檢查對于的數(shù)據(jù)塊是否在緩存中,如果不在緩存中,則通過數(shù)據(jù)塊淘汰算法,得到一個空閑的緩存塊,分配給請求的的數(shù)據(jù)塊,并向文件讀寫模塊發(fā)起讀請求;d)文件讀寫模塊從讀請求隊列中獲取一定數(shù)量的請求,并用異步的方式向操作系統(tǒng)遞交讀請求;e)文件讀寫模塊等待異步操作完成,并標(biāo)記完成讀取的緩存塊的可用位,以表示緩存塊中已經(jīng)包含有效數(shù)據(jù),可以被其他模塊使用。
全文摘要
本發(fā)明屬于網(wǎng)絡(luò)多媒體技術(shù)領(lǐng)域,具體涉及一個適用于帶時移IPTV直播服務(wù)器的專用磁盤讀寫系統(tǒng),以及使用該讀寫系統(tǒng)的帶時移IPTV直播服務(wù)器。其中磁盤讀寫系統(tǒng)包括媒體數(shù)據(jù)緩存服務(wù)器和若干緩存客戶端。緩存客戶端分為直播數(shù)據(jù)寫客戶端和直接數(shù)據(jù)讀客戶端;媒體數(shù)據(jù)緩存服務(wù)器包括頻道管理模塊、緩存管理模塊和文件讀寫模塊。緩存管理模塊采用基于tmpfs和內(nèi)存文件映射的內(nèi)存,文件讀寫模塊采用DIRECT I/O和異步I/O技術(shù)。使用所述讀寫系統(tǒng)的帶時移IPTV直播服務(wù)器還包括媒體數(shù)據(jù)預(yù)處理模塊、發(fā)送模塊和用戶管理模塊,媒體數(shù)據(jù)從預(yù)處理模塊經(jīng)專用磁盤讀寫系統(tǒng)傳輸給發(fā)送模塊,并最終發(fā)送到各個客戶端播放器,從而提高帶時移直播服務(wù)器的整體性能。
文檔編號G06F12/00GK101060418SQ20071004116
公開日2007年10月24日 申請日期2007年5月24日 優(yōu)先權(quán)日2007年5月24日
發(fā)明者朱陳潔, 黃澄, 葉德建 申請人:上海清鶴數(shù)碼科技有限公司