亚洲无码在线播放,欧美性爱一级在线视频,最新国产在线拍揄自揄视频,国产福利在线观看不卡视频,亚洲中文字幕aⅴ无码

<wbr id="au4ne"></wbr>
    1. <source id="au4ne"></source>

      測量數(shù)據(jù)庫(測量數(shù)據(jù)庫建立項(xiàng)目)

      發(fā)布時間:2024-08-18
      本文主要介紹調(diào)查數(shù)據(jù)庫(調(diào)查數(shù)據(jù)庫建立項(xiàng)目),下面一起看看調(diào)查數(shù)據(jù)庫(調(diào)查數(shù)據(jù)庫建立項(xiàng)目)相關(guān)資訊。
      在本文的開始,我們將介紹go-ycsb是如何使用的,然后我們將分析它是如何作為基準(zhǔn)測試使用的,以查看其優(yōu)缺點(diǎn)。
      轉(zhuǎn)載請聲明出處~,本文發(fā)表于羅志云 的博客:,這樣才能橫向比較不同數(shù)據(jù)庫的性能。
      ycsb,全稱是 雅虎!云服務(wù)基準(zhǔn)和測試是雅虎開發(fā)的一個工具,用于構(gòu)建云服務(wù)的測試,涵蓋常見的nosql數(shù)據(jù)庫產(chǎn)品,如cassandra、mongodb、hbase、redis等。
      作為一名圍棋開發(fā)者,我們使用pingcap開發(fā)的go ycsb對測試進(jìn)行了基準(zhǔn)測試。
      要安裝#,首先確保本地go版本不低于1.16,然后下載編譯:
      復(fù)制git clon-ycsb.gitcd go-ycsbmake在b in文件夾中有我們編譯的程序go-ycsb。
      讓 讓我們先看看工作負(fù)載文件夾。目錄中有各種工作負(fù)載模板,可以基于工作負(fù)載模板進(jìn)行定制和修改。默認(rèn)的六種測試場景如下:
      workloada:讀寫平衡型,50%/50%,reads/writesworkloadb:多讀少寫,95%/5%,reads/writesworkloadc:只讀,100%,readsworkloadd:讀取最近寫入的記錄,95%/5%,reads/insertworkloade。95%/5%,scan/ins測試。工作量中的操作主要包括:
      插入:插入新記錄更新:更新記錄的一個或所有字段讀取:讀取記錄的一個或所有字段。有字段掃描:從一個鍵中按順序隨機(jī)掃描隨機(jī)記錄。當(dāng)我們在測試時,我們需要根據(jù)不同的業(yè)務(wù)場景模擬測試,因此我們可以通過r測試階段操作的記錄數(shù)。如果設(shè)置了threadcount,那么每個線程操作的記錄數(shù)=操作數(shù)/threadcountoptioncount = 3000000 # thread count = 500 #如果一個表中已經(jīng)有記錄,那么在加載數(shù)據(jù)時,從這個記錄號開始。insertstart=0 #一行數(shù)據(jù)中的字段數(shù)。fieldcount=10 #每個字段的大小。fieldlength=100 #是否應(yīng)該加載所有字段?真的嗎?是否應(yīng)該更新所有字段?writeallfields=false #字段長度分布fieldlength distribution = constant # fieldlength distribution = uniform # fieldlength distribution = zipfian #讀取操作概率readproportion=0.95 #更新操作概率update proportion = 0 #插入操作概率insertproportion=0 #先讀取后寫入相同的記錄概率readmodifywriteproportion=0 #范圍操作概率scanproportion=0 #范圍操作,可操作記錄的最大數(shù)量maxscanlength=1000 #用于選擇掃描期間訪問的記錄數(shù)量的分布。iform # scanlength distribution = zipfian #記錄應(yīng)該順序插入還是偽隨機(jī)插入order = hashed # insert order = ordered #如何模擬測試requestdistribution = zipfian # request distribution = uniform # request distribution = latest #以下兩種,當(dāng)request distribution為熱點(diǎn)時#, 構(gòu)成熱點(diǎn)集的數(shù)據(jù)項(xiàng)百分比hotspotdatafraction=0.2 #訪問熱點(diǎn)集的數(shù)據(jù)操作百分比hotspotopnfraction=0.8 #操作數(shù)據(jù)表的表名=usertable #延遲了測量結(jié)果的展現(xiàn)形式,測量類型= histogram測試 #暫時沒有實(shí)現(xiàn)。 例如,如果我們現(xiàn)在想要測試 redis的性能,我們應(yīng)該首先編寫一個工作負(fù)載:
      copyrecordcount = 1000000 operation count = 1000000 workload = core read all fields = true readmodifywriteproportion = 1 request distribution = uniform redis . addr = 127.0。0.1 : 6379 thread count = 50上面的工作負(fù)載表示加載時,將有100萬條數(shù)據(jù)插入到庫中,要操作的數(shù)據(jù)量也是100萬,但有50個線程,即每個線程實(shí)際操作2萬行記錄;
      測試模式采用readmodifywriteproportion,先讀后寫,操作記錄采用uniform,即隨機(jī)模式。
      首先加載數(shù)據(jù):
      收到。/bin/go-ycsb load r測試:
      收到。/bin/go-ycsb runr: 18.8,count: 499312、ops: 26539.8、avg(us): 1388、min(us): 107、max(us): 42760、99th(us): 3000、99.9th(us): 7000、99.99th(us): 26000 tak測試總耗時;計數(shù):操作記錄的數(shù)量;ops:每秒運(yùn)算次數(shù),一般是運(yùn)算次數(shù),和qps差別不大;avg、min、max:平均、最小、最大單次記錄操作耗時;第99、99.9、99.99:p99、p99.9、p99.99延時;代碼實(shí)現(xiàn)分析#當(dāng)然,對我來說,肯定是要看它的代碼是怎么做的,了解一下老板是怎么寫代碼的也很有幫助。
      對于go ycsb,它總共有幾個組件:
      工作負(fù)載:加載初始化配置文件,創(chuàng)建一個線程執(zhí)行測試;客戶端:封裝工作負(fù)載、配置參數(shù)、數(shù)據(jù)庫等。,并用于運(yùn)行測試;db:配置了一堆可執(zhí)行的數(shù)據(jù)庫客戶端來讀寫特定的數(shù)據(jù)庫;測量:數(shù)據(jù)統(tǒng)計模塊,統(tǒng)計執(zhí)行次數(shù),時間延遲等。讓 讓我們以redis為例,看看如果我們想要測試 ;自己的數(shù)據(jù)庫。
      在go ycsb中定義db#,所有的db都放在db:
      所以,我們可以在這個文件夾下創(chuàng)建自己的db,然后構(gòu)造一個struct來實(shí)現(xiàn)db的接口:
      copytype db接口{ tosqldb *sql。db close錯誤initthread(ctx上下文。context,threadid int,threadcount int)上下文。上下文cleanupthread(ctx上下文。上下文)讀取(ctx上下文。context,table string,key string,fields[]string)(map[string][]字節(jié),error)掃描(ctx上下文。context,table string,startkey string,count int,fields[]string)([]map[string][]byte,error) update(ctx context。上下文,表字符串,鍵字符串,值映射[字符串][]字節(jié))錯誤插入(ctx上下文。上下文、表字符串、鍵字符串、值映射[字符串] []字節(jié))錯誤刪除(ctxcontext。context,tablestring,keystring) error}定義特定的db操作。
      然后,您需要定義一個工廠來創(chuàng)建這個db結(jié)構(gòu)并實(shí)現(xiàn)dbcreator接口:
      復(fù)制類型dbcreator接口{create (p * properties。properties) (db,error)}然后您需要定義一個init函數(shù)在啟動時注冊dbcreator:
      copyfunc init {ycsb。registerdbcreator( redis ,rediscreator { })} var db creators = map[string]dbcreator { } func registerdbcreator(name string,creator dbcreator) {_,ok : = db creators[name]if ok { panic(fmt . sprintf( 重復(fù)的注冊數(shù)據(jù)庫% s ,name))} dbcreators[name]= creator } register dbcreator在初始化時會被調(diào)用。用于獲取由init方法注冊的數(shù)據(jù)庫。這樣go ycsb實(shí)現(xiàn)了db的定制化。
      全局參數(shù)初始化#首先,go ycsb會根據(jù)傳入的是load還是run,使用cobra執(zhí)行以下兩種不同的方法:
      copy func runloadcommandfunc(cmd * cobra.command,args[]string){ runclientcommandfunc(cmd,args,false)} func runtranscommandfunc(cmd * cobra . command,args[]string){ runclientcommandfunc(cmd,args,true)}這將被調(diào)用到runclientcommandfunc函數(shù)中。
      copy func runclientcommandfunc(cmd * cobra . command,args [] string,do transactions bool){ dbname : = args[0]//初始化全局參數(shù)initialglobal (dbname,func{ dotranslag : = 。do transactions { do transflag = 虛假 }globalprops。設(shè)置(道具。dotransactions,dotransflag)如果cmd。標(biāo)志。已更改( 線程和){//我們通過命令行設(shè)置threadarg . global props . set(prop。threadcount,strconv。itoa(threadsarg))}if cmd。標(biāo)志。已更改( 目標(biāo) ){globalprops。設(shè)置(道具。目標(biāo),strconv。itoa(target arg))}如果cmd。標(biāo)志。已更改( 音程 ){globalprops。設(shè)置(道具。loginterval,strconv。itoa(reportinterval))}})fmt。println( ****************屬性* * * * * * * * * * * * )對于key,值: = range global props。map {fmt。printf( \ % s \ = \ % s \ \ n ,key,value)}fmt。println( ********************** * * * * * * * * * * * * * * * * * * )//初始化client : = client . new client(全局道具,全局工作量,globaldb)啟動: = time . now//運(yùn)行測試.run(global cont測試結(jié)果輸出測量。output}參數(shù)主要在initialglobal中完成:
      copy func initial global(dbname string,onproperties func) {...go func {http。listenandserve(addr,nil)}//初始化測量measurement。init measure(global props)iflen(tablename)= = 0 { tablename = global props . getstring(prop . tablename,prop。tablename default)}//get workloadcreatorworkloadname : = global props . getstring(prop . workload, 核心 )工作負(fù)荷創(chuàng)建者: = ycsb . get workload creator(工作負(fù)荷名稱)//創(chuàng)建工作負(fù)荷var errorif全局工作負(fù)荷,err = workload creator.create(全局道具);呃!= nil {util。fatalf( 創(chuàng)建工作負(fù)荷% s失敗,工作負(fù)荷名稱,err)}/get dbdbcreator : = ycsb . get dbcreator(dbname)if dbcreator = = nil { util . fatalf( %s沒有注冊,dbname)}/create dbif globaldb,err = dbcreator . create(global props);呃!= nil { util . fatalf( createdb% s失敗,dbname,err)} global db = client . db wrapper { global db } }這里最重要的是創(chuàng)建工作負(fù)載和db。工作負(fù)載將初始化配置文件中的大量信息。
      運(yùn)行測試 # runclientcommandfunc將調(diào)用客戶端 執(zhí)行測試的運(yùn)行方法:
      copyfunc (c *client)運(yùn)行(ctx上下文。上下文){var wg sync。waitgroupthreadcount : = c . p . getint(prop。線程計數(shù),1)wg。add(threadcount)measurectx,measure cancel : = context。with cancel(ctx)measure ch : = make(chan struct { },1)go func{ defer func{ measure ch-struct { } { }/這個很有意思,因?yàn)橛袝r候我們在做數(shù)據(jù)庫的時候需要初始化緩存中的數(shù)據(jù)//這樣我們就可以 測試統(tǒng)計中不算初期,這里有熱身時間??梢耘渲胏 . p . get bool(prop . do transactions,true){ dure cho 45-@ .com = c . p . getint 64(prop . warm uptime,0)選擇{case-ctx。done: return case-time . after(time . dur)* time . second): } }//測量。:= time。newticker(時間。持續(xù)時間*時間。第二)defer t.stopfor {select {//輸出統(tǒng)計信息case-t . c: measurement . outputcase-measure ctx . done: return } }//做一些初始化工作,比如mysql需要創(chuàng)建一個表if err: = c . err!= nil { fmt . printf( 初始化工作負(fù)載失敗,err)return }//根據(jù)threadcount為i := 0創(chuàng)建多個線程操作數(shù)據(jù)庫;我threadcounti { go func(threadid int){ defer wg . done//initialize worker : = new worker(c . p,threadid,threadcount,c.workload,c.db)ctx : = c . workload . init thread(ctx,threadid,thread count)ctx = c . db . init thread(ctx,threadid,threadcount)//開始運(yùn)行測試w.run(ctx)//運(yùn)行測試后,做清理工作c . dbwaitmeasure cancel-measure ch }這個分為兩部分:第一部分是創(chuàng)建一個線程,這個線程會控制是否啟動測試統(tǒng)計,然后每10秒輸出一次統(tǒng)計信息;第二部分是根據(jù)設(shè)置的threadcount創(chuàng)建一個線程,并運(yùn)行work測試。
      新工人根據(jù)operationcount設(shè)置totalopcount,表示要執(zhí)行的總次數(shù),設(shè)置totalopcount/int64(threadcount)表示單線程操作的記錄數(shù)。
      復(fù)制func (w * worker)運(yùn)行(ctxcontext。context){//分發(fā)線程操作,這樣它們就不會 不要同時打db。如果w . targetopsperms 0.0 w . targetopsperms = 1.0 { time。睡眠(時間。持續(xù)時間(蘭特。int 63n(w . targetopstickns))} start time : = time。now//循環(huán)直到操作數(shù)到達(dá)opsdonefor w . op count = = 0 | | w . opsdonew . op count { var err err count : = 1//這里是執(zhí)行基準(zhǔn)測試 if w . do transactions { if w . do batch { err = w . workload . dobatch transaction(ctx,w.batchsize,w . work db)ops count = w . batch size } else { err = w . workload . do transaction(ctx,w.workdb)}//這里是iswarupfinished{ w . ops done = int 64(ops count)w . throttle(ctx,開始時間)} select {case-ctx。done: return default : } }基準(zhǔn)測試的具體實(shí)現(xiàn)就交給工作了。負(fù)載與負(fù)載 dotransaction方法來確定執(zhí)行。
      copy func(c * core)do transaction(ctx上下文。上下文,dbycsb。db)錯誤{ state : = ctx。值(statekey)。(* corestate)re: = stat測試場景,進(jìn)入不同的測試分支// next方根據(jù)設(shè)置的readproportion、updateproportion、scanproportion等概率得到相應(yīng)的操作類型-@ .com = operation type(c . operation chooser . next(r))。開關(guān)操作{ case read: return c . dotransactionread(ctx,db,state)case update : return c . dotransactionupdate(ctx,db,state)case insert : return c . dotransactioninsert(ctx,db,state)case scan: return c . dotransactionscan(ctx,db,state)default : return c . dotransactionread modify(ctx
      這個算法很簡單。在初始化operationchooser時,將readproportion、updateproportion、scanproportion等設(shè)置參數(shù)的值以數(shù)組的形式加到operationchooser的值上,然后隨機(jī)選取一個0~1的小數(shù),檢查這個隨機(jī)數(shù)落在哪個范圍內(nèi)。
      copy func(d * discrete)next(r * rand。跑d)int 64 { sum : = float 64(0)for _,p : = range d . values { sum = p . weight }//random a decimal val : = r . float 64(。p : = range d . values { pw : = p . weight/sumif val pw { d . setlastvalue(p . value)return p . value } val-= pw } panic( 哎呀,不應(yīng)該到這里。 )}在代碼實(shí)現(xiàn)方面,通過將所有值相加得到sum,然后計算每個值的比例是否達(dá)到隨機(jī)值。
      最后,讓 讓我們看看dotransactionread是如何實(shí)現(xiàn)的:
      copy func(c * core)dotransactionread(ctx上下文。上下文,db ycsb。db,state * corestate)error { r : = state . r//獲取一個鍵值keynum : = c . next keynum(state)根據(jù)我們設(shè)置的requestdistribution,keyname: = c . build keyname(keynum)//讀取字段varfields [] stringiff!c.readallfields {//如果沒有讀取所有字段,那么根據(jù)fieldchooser選擇一個字段執(zhí)行字段名: = state . field names[c . field chooser . next(r)]fields = append(fields,fieldname)} else {fields = state。field names }//調(diào)用db的read方法值,err : = db . read(ctx,c.table,keyname,fields) if err!= nil {return err}//檢查數(shù)據(jù)完整性if c . data integrity { c . verify row(state,keyname,values)} return nil}這里會調(diào)用nextkeynum先獲取鍵值,這里的key會根據(jù)我們設(shè)置的requestdistribution參數(shù)按照一定的規(guī)則獲取。然后調(diào)用dbwrapper的read方法,在檢查需要讀取哪些字段后讀取數(shù)據(jù)。
      copyfunc (db dbwrapper) read(ctx上下文。context,table string,key string,fields[]string)(_ map[string][]byte,error){ start: = time . nowdefer func{//進(jìn)行測試統(tǒng)計量(start, 閱讀 ,err)} return db.db.read (ctx,表,鍵,字段)} db wrapper會封裝一個層,使用defer wrapper。
      但我在這里的問題是,在讀取數(shù)據(jù)時,會根據(jù)傳入的字段進(jìn)行解析,這也會損失一些性能。不知道是否合理,比如redis的read方法:
      copyfunc (r *redis) read(ctx上下文。context,table string,key string,fields[]string)(map[string][]byte,error){ data : = make(map[string][]byte,len(fields))res,err : = r . cli:按字段過濾返回數(shù)據(jù),err} statistics #它將在每次操作后進(jìn)行調(diào)整。采用測量法對測試數(shù)據(jù)進(jìn)行統(tǒng)計。
      復(fù)制funcmeasure (starttime。time,opstring,err error){//需要時間計算lan: = time . now。如果出錯,則執(zhí)行sub (start )!=零{測量值。測量(fmt。sprintf( %s錯誤 ,op),lan) return}測量。measure (op,lan)} statistics由于將有多個線程同時運(yùn)行,因此有必要以線程安全的運(yùn)行:
      復(fù)制函數(shù)(h *直方圖)測量(等待時間。持續(xù)時間){//這是us微秒n : = int 64(latency/time .微秒)原子。add 64(h . sum,n)原子。addint64(h.count,1)//這里轉(zhuǎn)換成ms bound : = int(n/h . bound interval)//bound counts是并發(fā)映射。用于統(tǒng)計每個時間段內(nèi)的操作次數(shù)(單位:ms)。h .受約束的縣。upsert (bound,1,func (ok bool,existed value int 64,new value int 64)int 64 { if ok { return existing value new value } return new value })//設(shè)置{ old min : = atomic . load int 64(h . min)的最小延遲。if n = oldmin {break}if atomic。compareandswapint64(h.min,oldmin,n) {break}}//設(shè)置{ oldmax: = atomic的最大延遲。load int 64(h . max)if n = old max { break } if atomic。compareandswapint64 (h.max,oldmax,n) {break}}每個時間段的統(tǒng)計數(shù)據(jù)(h.max,n)}}undcounts是go ycsb自己實(shí)現(xiàn)的保證線程安全的concurrentmap,用于統(tǒng)計單位時間內(nèi)的運(yùn)算次數(shù);
      最大和最小延遲是通過cas操作的,也是為了確保線程安全。
      統(tǒng)計完成后將調(diào)用getinfo計算耗時:
      copy func(h *直方圖)getinfomap[string]interface { } { min : = atomic。load int 64(h . min)max : = atomic。load int 64(h . max)sum : = atomic。load int 64(h . sum)count : = atomic。load int 64(h . count)bounds : = h . boundcounts . keyssort。ints(bounds)avg : = int 64(float 64(sum)/float 64(count))per 99 : = 0 per 999 : = 0 per 999 : = 0 pcount: = int 64(0)//計算p99,p99.9,p99.99//這其實(shí)是一個比例的統(tǒng)計。// bound將為_,bound cho 45-@ .com = range bounds { boundcount,_ : = h . boundcounts . get(bound)op count = boundcountper : = float 64(op count)/float 64(count)//下面是per99 = = 0 per = 0.99 { per99 =(bound 1)* 1000時99%的操作落在哪個時間間隔內(nèi)}//計算經(jīng)過的: = time . now。sub (h .開始時間)。seconds//計算單位時間內(nèi)的運(yùn)算次數(shù)qps : = float 64(count)/elapsedres : = make(map[string]interface { })res[elapsed]= elapsedres[count]= count res[qps]= qpsres[avg]= avgres[min]= minres[max]= maxres[per 99 th]= per 99 res[per 999 th]= per 999 res[per 999 th]= per 999 returnres }
      總結(jié)#通過以上分析可以發(fā)現(xiàn),go ycsb設(shè)計還是很精妙的,用很少的代碼就可以擴(kuò)展db;配置也相當(dāng)靈活,可以根據(jù)不同的r測試環(huán)境,在測試可以隨意調(diào)整讀寫概率,保證盡可能模擬在線環(huán)境。
      然而,它也有許多缺點(diǎn)。一方面文檔很不充分,基本只寫了幾個參數(shù)配置;另一方面,許多功能還沒有實(shí)現(xiàn),在線測試經(jīng)常出現(xiàn)錯誤。你看代碼,結(jié)果沒有實(shí)現(xiàn)。三年前,作者在他的博客中說,應(yīng)該實(shí)現(xiàn)測試結(jié)果導(dǎo)出功能,但結(jié)果尚未實(shí)現(xiàn)。我已經(jīng)給作者tl@pingcap.com發(fā)了一封電子郵件,等待回復(fù)。
      referenc-ycsb
      github . com/brianfrankcooper/ycsb/wiki/running-a-workload
      標(biāo)簽:
      測試行動
      了解更多調(diào)查數(shù)據(jù)庫(調(diào)查數(shù)據(jù)庫建立項(xiàng)目)相關(guān)內(nèi)容請關(guān)注本站點(diǎn)。
      上一個:京東展示L4級無人駕駛卡車等黑科技
      下一個:實(shí)驗(yàn)分析質(zhì)量控制

      離婚后對財產(chǎn)分割有異議如何辦
      HAWE哈威滑閥式換向閥概述
      紫外激光打標(biāo)機(jī)的工作原理及應(yīng)用范圍
      2019適合伴娘唱的歌有哪些
      22家環(huán)保企業(yè)入選CITI指數(shù)報告,固廢領(lǐng)域備受矚目
      混凝土收縮膨脹儀操作規(guī)程
      蒸發(fā)結(jié)晶器蒸發(fā)量與什么有關(guān)
      什么叫水泵的同心度?什么叫聯(lián)軸器?
      鮮肉預(yù)冷排酸庫加濕器,冷卻排酸冷庫加濕機(jī)器
      美國夏威夷海運(yùn)特殊條款(美國海運(yùn)目前狀況)