劉王飛
(1.閩南師范大學(xué)計(jì)算機(jī)學(xué)院,福建 漳州 363000;2.閩南師范大學(xué)數(shù)據(jù)科學(xué)與智能應(yīng)用福建省高等學(xué)校重點(diǎn)實(shí)驗(yàn)室,福建 漳州 363000)
大數(shù)據(jù)時(shí)代背景下,數(shù)據(jù)庫(kù)云平臺(tái)需要存儲(chǔ)和管理來(lái)自云端不用地點(diǎn)、不用用戶的大量數(shù)據(jù),數(shù)據(jù)記錄需要一個(gè)UUID(universally unique IDentifier)來(lái)作唯一標(biāo)識(shí),它的生成方法關(guān)系著平臺(tái)的整體運(yùn)行效率.目前常用的UUID 方法是RFC 4122的UUID 算法[1]和Twitter公司的雪花算法[2]實(shí)現(xiàn).但是UUID 算法是無(wú)序的,不利于索引.雪花算法需要讀取數(shù)據(jù)中心,在云平臺(tái)中不易獲取[2].于是提出一種新的UUID 生成方法,使得UUID 是一個(gè)有規(guī)律的序列,并設(shè)計(jì)了一個(gè)基于微服務(wù)架構(gòu)的數(shù)據(jù)庫(kù)云平臺(tái),在該平臺(tái)上用新的UUID算法生成任務(wù)ID,提高任務(wù)存儲(chǔ)索引與管理的效率.
UUID(universally unique IDentifier,通用唯一標(biāo)識(shí)符)在分布式系統(tǒng)中用來(lái)標(biāo)識(shí)數(shù)據(jù)記錄.RFC 4122定義的UUID設(shè)計(jì)為一個(gè)128位的二進(jìn)制數(shù),以十六進(jìn)制的形式表示,分5段,段與段之間用“-”連接,記錄為“********-****-X***-Y***-************”.其中X 為版本字段,UUID 目前有5個(gè)版本,所以X 的取值為1、2、3、4、5,分別對(duì)應(yīng)相應(yīng)版本.Y 為變量字段,目前定義為10**,所以取值為8、9、a、b.UUID-1、UUID-2由隨機(jī)數(shù)、時(shí)間、主機(jī)物理地址生成;UUID-3、UUID-5 由命名空間的散列值生成;UUID-4 由隨機(jī)數(shù)生成.UUID-1 與UUID-2 的生成元素包含了主機(jī)物理地址,容易暴露客戶信息.UUID-3 與UUID-5 在相同的用戶主機(jī)上生成的UUID 是一樣的,因此不適用于數(shù)據(jù)庫(kù)云平臺(tái).同時(shí)UUID 方法是基于隨機(jī)數(shù)的,由此生成的UUID 是一個(gè)無(wú)結(jié)構(gòu)、無(wú)規(guī)律的符號(hào).在數(shù)據(jù)庫(kù)云平臺(tái)中需要對(duì)大量的任務(wù)進(jìn)行索引,如用UUID 算法生成任務(wù)ID,是一個(gè)無(wú)序的編號(hào),造成索引與任務(wù)管理的效率低下.
MD5 算法是Ronald Rivest 于1991年提出的一種數(shù)據(jù)加密算法[3],它可以將隨機(jī)長(zhǎng)度的信息生成128 bit的信息摘要[4],數(shù)據(jù)安全性較高.在新的UUID算法中被用來(lái)對(duì)主機(jī)名進(jìn)行加密,實(shí)現(xiàn)對(duì)用戶主機(jī)信息的隱藏.
第一代微服務(wù)架構(gòu)需要開(kāi)發(fā)人員實(shí)現(xiàn)繁瑣的外圍功能.第二代微服務(wù)架構(gòu)以Spring Cloud框架為代表,框架已包含外圍功能,但需要開(kāi)發(fā)人員理解、配置、使用這些框架.第三代微服務(wù)技術(shù)Service Mesh[5]解決了上述問(wèn)題,開(kāi)發(fā)人員只需按照普通應(yīng)用程序的形式開(kāi)發(fā)功能,專注于服務(wù)的業(yè)務(wù)功能.為了測(cè)試新UUID算法的性能,基于第三代微服務(wù)技術(shù)Service Mesh設(shè)計(jì)了一個(gè)數(shù)據(jù)庫(kù)云平臺(tái),利用新UUID算法生成任務(wù)ID.
新的UUID 生成方法的思路是:首先設(shè)定機(jī)器不同,則生成的ID 不同.同一機(jī)器,進(jìn)程不同,那么ID不同.同一進(jìn)程,時(shí)間不同,那么ID不同.同一時(shí)間,自增數(shù)不同,那么ID不同.新的UUID由主機(jī)名、進(jìn)程號(hào)、時(shí)間、自增數(shù)這四元素構(gòu)建產(chǎn)生.主機(jī)名是當(dāng)前用戶主機(jī)的Host Name,為隱藏用戶的機(jī)器信息,取主機(jī)名的MD5值;時(shí)間是當(dāng)前系統(tǒng)時(shí)間的毫秒數(shù);自增數(shù)是為了區(qū)分同主機(jī)、同進(jìn)程、同時(shí)間產(chǎn)生的UUID,每新增一個(gè)UUID,自增數(shù)加1,初始值設(shè)定為0.因時(shí)間、自增數(shù)、進(jìn)程號(hào)是一個(gè)有序的序列,所以設(shè)置在前面.新的UUID 的128 位二進(jìn)制設(shè)計(jì)為四段:時(shí)間(48 bit)、自增數(shù)(16 bit)、進(jìn)程號(hào)(32 bit)、主機(jī)名的MD5值(32 bit),以十六進(jìn)形式表示,每段用“-”連接.
偽代碼實(shí)現(xiàn)如下:
數(shù)據(jù)結(jié)構(gòu):
long currentTimeMillis;//當(dāng)前毫秒數(shù)
short sequenceInCurrentTimeMillis=0;//自增數(shù)從0開(kāi)始
int processID;//進(jìn)程號(hào)
int hostID;//主機(jī)名
程序流程:1)獲取進(jìn)程ID:pocessName=ManagementFactory.getRuntimeMXBean().getName();this.processID=Integer.parseInt(processName.split("@")[0]);2)獲取主機(jī)ID:hostname=InetAddress.getLocal-Host().getHostName();this.hostID=hostname 的MD5 值;3)獲取當(dāng)前毫秒數(shù):currentMilliseconds=System.currentTimeMillis();4)獲取自增數(shù):最近一次取得的當(dāng)前毫秒數(shù)lastCurrentTimeMillis 初始化為0;如果(lastCurrentTimeMillis==currentMilliseconds) {sequenceInCurrentTimeMillis++;如果自增數(shù)用完,即(sequenceInCurrentTimeMillis==0),獲取新的currentMilliseconds;}否則sequenceInCurrentTimeMillis=0;更新最近取得的當(dāng)前毫秒數(shù)lastCurrentTimeMillis=currentMilliseconds;5)將當(dāng)前毫秒數(shù)、自增數(shù)、進(jìn)程ID、主機(jī)ID 進(jìn)行拼接:Long.toHexString(currentMilliseconds)+ "-" + Short.toString(sequenceInCurrentTimeMillis)+"-"+Integer.toHexString(processID)+"-"+Integer.toHexString(hostID).
新UUID 的時(shí)間占48 位,以ms 為單位,使用年限可達(dá)8 925年.自增數(shù)占16 位,可同時(shí)生成65 535 個(gè)ID,具有高并發(fā)性.
數(shù)據(jù)庫(kù)云平臺(tái)采用微服務(wù)架構(gòu)設(shè)計(jì),由一臺(tái)中央控制機(jī)和多臺(tái)受控機(jī)組成.云平臺(tái)共5 個(gè)模塊,其中Agent模塊部署在受控機(jī)上,其他管理模塊、接口模塊、調(diào)度模塊、遠(yuǎn)程控制模塊等4個(gè)模塊部署在中央控制機(jī)上.其模型框架如圖1所示.中央控制機(jī)中的4 個(gè)模塊以微服務(wù)的形式運(yùn)行,部署于Kubernetes 容器中.微服務(wù)之間調(diào)用采用了基于Istio 的第三代微服務(wù)治理技術(shù)Service Mesh.基礎(chǔ)設(shè)施(Apache Kafa消息隊(duì)列、Redis緩存、MongoDB文檔型數(shù)據(jù)庫(kù)、MySQL關(guān)系型數(shù)據(jù)庫(kù))以Docker組件的方式部署.
圖1 數(shù)據(jù)庫(kù)云平臺(tái)模型框架Fig.1 Framework of Database cloud platform
在設(shè)計(jì)的數(shù)據(jù)庫(kù)云平臺(tái)中分別使用UUID-1、UUID-3、UUID-4、UUID-5算法(UUID-2與UUID-1只有個(gè)別位不同,未列舉).與新的UUID算法生成任務(wù)ID,圖2所示為獲取的原UUID與新UUID的對(duì)比圖.如圖2(a),“f0038c39bcba”為用戶主機(jī)的物理地址,暴露了用戶信息.除此之外,通過(guò)對(duì)比,從圖2(e)中可以看出新的UUID是一個(gè)有規(guī)律的序列,而圖2(a)、(b)、(c)、(d)所示的原UUID是一個(gè)隨機(jī)序列.結(jié)果表明新UUID在平臺(tái)的大量任務(wù)索引中具有明顯優(yōu)勢(shì).
圖2 原UUID與新UUID對(duì)比圖Fig.2 Comparison of original UUID and new UUID
提出的新的UUID算法引入時(shí)間毫秒數(shù)、進(jìn)程ID、自增數(shù),使得生成的UUID變成一個(gè)有規(guī)律的序列.并且主機(jī)名采用了MD5 的加密,有效地保證了用戶安全.新的UUID 算法運(yùn)用于設(shè)計(jì)的基于微服務(wù)架構(gòu)的數(shù)據(jù)庫(kù)云平臺(tái),在任務(wù)ID 生成過(guò)程中由于它的規(guī)律性,在索引與管理方面具有明顯的優(yōu)勢(shì).在Javascript中最大支持53 位的數(shù)值,新的UUID 還是一個(gè)128 位的編碼,需要截取,在后續(xù)工作中將進(jìn)一步研究UUID對(duì)瀏覽器的兼容性.