国产精品久久久久久2021,日韩精品无码av中文无码版,亚洲精品久久久午夜麻豆,无码成人精品日本动漫纯h

010-68421378
當(dāng)前您所在的位置:首頁>新聞中心>新品發(fā)布

Wowza技術(shù):如何在多個(gè)GPU之間實(shí)現(xiàn)負(fù)載均衡?

發(fā)布時(shí)間:2020/12/25 瀏覽量:3813
Wowza Streaming Engine已經(jīng)實(shí)現(xiàn)了多個(gè)GPU之間的負(fù)載均衡

從4.6.0版本開始,在利用NVIDIA CUDA硬件進(jìn)行加速編解碼時(shí),Wowza Streaming Engine已經(jīng)實(shí)現(xiàn)了多個(gè)GPU之間的負(fù)載均衡。與此同時(shí),Wowza還提供了相應(yīng)的API接口,這樣可以讓你按你自己的需求和邏輯實(shí)現(xiàn)自己需要的負(fù)載均衡功能。 

 

下面這篇文章就是對(duì)它們的介紹。 

注意:本功能需要Wowza Streaming Engine™ 4.6.0及以上版本的支持。

Wowza Transcoder在運(yùn)行時(shí)會(huì)調(diào)用下面的Interface ITranscoderVideoLoadBalancer

public interfaceITranscoderVideoLoadBalancer

{

         publicabstract void init(IServer server, TranscoderContextServertranscoderContextServer);

         publicabstract void onHardwareInspection(TranscoderContextServertranscoderContextServer);

         publicabstract void onTranscoderSessionCreate(LiveStreamTranscoderliveStreamTranscoder);

         publicabstract void onTranscoderSessionInit(LiveStreamTranscoderliveStreamTranscoder);

         publicabstract void onTranscoderSessionDestroy(LiveStreamTranscoderliveStreamTranscoder);

         publicabstract void onTranscoderSessionLoadBalance(LiveStreamTranscoderliveStreamTranscoder);

}

其中:

 

配置 ITranscodeVideoLoadBalancer 接口的實(shí)現(xiàn)類


要使用ITranscoderVideoLoadBalancer接口,你需要按以下操作: 

  1. 創(chuàng)建一個(gè)class,繼承TranscoderVideoLoadBalancerBase (它實(shí)現(xiàn)了上面介紹的ITranscoderVideoLoadBalancer接口),然后重載接口中的方法。然后在[install-dir]/conf/Server.xml文件中的添加一個(gè)server級(jí)別的參數(shù),指明這個(gè)實(shí)現(xiàn)類的完整類包名:

?

 

?

   transcoderVideoLoadBalancerClass

?

   [custom-class-path]

 

 

其中[custom-class-path]就是你的實(shí)現(xiàn)類的完整類包名。例如,如果你使用的就是Wowza內(nèi)部自帶的這個(gè)TranscoderVideoLoadBalancerCUDASimple實(shí)現(xiàn)類,你就該按下面配置: 

 

         transcoderVideoLoadBalancerClass

         com.wowza.wms.transcoder.model.TranscoderVideoLoadBalancerCUDASimple

 

?

(可選)如果你的多個(gè)GPU性能各不一樣,你還可以用transcoderVideoLoadBalancerCUDASimpleGPUWeights 參數(shù)為每一個(gè)GPU設(shè)置不同的權(quán)重。
   

例子 class - TranscoderVideoLoadBalancerCUDASimple


從Wowza StreamingEngine (4.5.0.01)開始,TranscoderVideoLoadBalancerCUDASimple) 就已經(jīng)內(nèi)置在Wowza中了。你不用做任何開發(fā)工作就可以直接使用。它的負(fù)載均衡機(jī)制是將每一個(gè)獨(dú)立的轉(zhuǎn)碼任務(wù)(session)的所有工作都分配在一個(gè)GPU上,也就說一個(gè)轉(zhuǎn)碼任務(wù)內(nèi)部的工作不會(huì)在多個(gè)GPU之間來回切換。 

import java.util.*;

 

import com.wowza.util.*;

import com.wowza.wms.application.*;

import com.wowza.wms.logging.*;

import com.wowza.wms.media.model.*;

import com.wowza.wms.server.*;

 

public classTranscoderVideoLoadBalancerCUDASimple extends TranscoderVideoLoadBalancerBase

{

         privatestatic final Class.class;

         privatestatic final String CLASSNAME ="TranscoderVideoLoadBalancerCUDASimple";

        

         publicstatic final int DEFAULT_GPU_WEIGHT_SCALE = 1;

         publicstatic final int DEFAULT_WEIGHT_FACTOR_ENCODE = 5;

         publicstatic final int DEFAULT_WEIGHT_FACTOR_DECODE = 1;

         publicstatic final int DEFAULT_WEIGHT_FACTOR_SCALE = 1;

        

         publicstatic final int LOAD_MAG = 1000;

        

         publicstatic final String PROPNAME_TRANSCODER_SESSION ="TranscoderVideoLoadBalancerCUDASimpleSessionInfo";

        

         classSessionInfo

         {

                   privateint gpuid = 0;

                   privatelong load = 0;

                  

                   publicSessionInfo(int gpuid, long load)

                   {

                            this.gpuid= gpuid;

                            this.load= load;

                   }

         }

        

         classGPUInfo

         {

                   privateint gpuid = 0;

                   privatelong currentLoad = 0;

                   privateint weight = 0;

                  

                   privateint getWeight()

                   {

                            returnthis.weight;

                   }

                  

                   privatelong getUnWeightedLoad()

                   {

                            returncurrentLoad;

                   }

                  

                   privatelong getWeightedLoad()

                   {

                            longload = 0;

                            if(weight > 0)

                                     load= (currentLoad*gpuWeightScale)/weight;

                            returnload;

                   }

         }

        

         privateObject lock = new Object();

         privateTranscoderContextServer transcoderContextServer = null;

         privateboolean available = false;

         privateint countGPU = 0;

         privateint gpuWeightScale = DEFAULT_GPU_WEIGHT_SCALE;

         privateint[] gpuWeights = null;

         privateint weightFactorEncode = DEFAULT_WEIGHT_FACTOR_ENCODE;

         privateint weightFactorDecode = DEFAULT_WEIGHT_FACTOR_DECODE;

         privateint weightFactorScale = DEFAULT_WEIGHT_FACTOR_SCALE;

         privateGPUInfo[] gpuInfos = null;

 

         @Override

         publicvoid init(IServer server, TranscoderContextServer transcoderContextServer)

         {

                   this.transcoderContextServer= transcoderContextServer;

                  

                   WMSPropertiesprops = server.getProperties();

                  

                   this.weightFactorEncode=props.getPropertyInt("transcoderVideoLoadBalancerCUDASimpleWeightFactorEncode",this.weightFactorEncode);

                   this.weightFactorDecode=props.getPropertyInt("transcoderVideoLoadBalancerCUDASimpleWeightFactorDecode",this.weightFactorDecode);

                   this.weightFactorScale=props.getPropertyInt("transcoderVideoLoadBalancerCUDASimpleWeightFactorScale",this.weightFactorScale);

 

                   StringweightsStr =props.getPropertyStr("transcoderVideoLoadBalancerCUDASimpleGPUWeights",null);

                   if(weightsStr != null)

                   {

                            String[]values = weightsStr.split(",");

                            intmaxWeight = 0;

                            this.gpuWeights= new int[values.length];

                            for(inti=0;i

                            {

                                     Stringvalue = values[i].trim();

                                     if(value.length() <= 0)

                                     {

                                               this.gpuWeights[i]= -1;

                                               continue;

                                     }

 

                                     intweight = -1;

                                     try

                                     {

                                               weight= Integer.parseInt(value);

                                               if(weight < 0)

                                                        weight= 0;

                                     }

                                     catch(Exceptione)

                                     {

                                     }

                                    

                                     this.gpuWeights[i]= weight;

                                     if(weight > maxWeight)

                                               maxWeight= weight;

                            }

                           

                            this.gpuWeightScale= maxWeight;

                            for(inti=0;i

                            {

                                     if(this.gpuWeights[i] < 0)

                                               this.gpuWeights[i]= this.gpuWeightScale;

                            }

                   }

                  

                   WMSLoggerFactory.getLogger(CLASS).info(CLASSNAME+".init:weightFactorEncode:"+weightFactorEncode+"weightFactorDecode:"+weightFactorDecode+"weightFactorScale:"+weightFactorScale);

         }

 

         @Override

         publicvoid onTranscoderSessionCreate(LiveStreamTranscoder liveStreamTranscoder)

         {

         }

 

         @Override

         publicvoid onTranscoderSessionInit(LiveStreamTranscoder liveStreamTranscoder)

         {

         }

 

         @Override

         publicvoid onTranscoderSessionDestroy(LiveStreamTranscoder liveStreamTranscoder)

         {                

                   if(this.countGPU > 1)

                   {

                            WMSPropertiesprops = liveStreamTranscoder.getProperties();

                            ObjectsessionInfoObj = props.get(PROPNAME_TRANSCODER_SESSION);

                            if(sessionInfoObj != null && sessionInfoObj instanceof SessionInfo)

                            {

                                     SessionInfosessionInfo = (SessionInfo)sessionInfoObj;

                                    

                                     if(sessionInfo.gpuid < gpuInfos.length)

                                     {

                                               synchronized(this.lock)

                                               {

                                                        gpuInfos[sessionInfo.gpuid].currentLoad-= sessionInfo.load;

                                                        sessionInfo.load= 0;

                                               }

                                              

                                     WMSLoggerFactory.getLogger(CLASS).info(CLASSNAME+".onTranscoderSessionDestroy["+liveStreamTranscoder.getContextStr()+"]:Removing GPU session: gpuid:"+sessionInfo.gpuid+"load:"+sessionInfo.load);

                                     }

                            }

                   }

         }

        

         @Override

         publicvoid onHardwareInspection(TranscoderContextServer transcoderContextServer)

         {                

         //{"infoCUDA":{"availabe":true,"availableFlags":65651,"countGPU":1,"driverVersion":368.81,"cudaVersion":8000,"isCUDAOldH264WindowsAvailable":false,"gpuInfo":[{"name":"GeForceGTX960M","versionMajor":5,"versionMinor":0,"clockRate":1097500,"multiprocessorCount":5,"totalMemory":2147483648,"coreCount":640,"isCUDANVCUVIDAvailable":true,"isCUDAH264EncodeAvailable":true,"isCUDAH265EncodeAvailable":false,"getCUDANVENCVersion":5}]},"infoQuickSync":{"availabe":true,"availableFlags":537,"versionMajor":1,"versionMinor":19,"isQuickSyncH264EncodeAvailable":true,"isQuickSyncH265EncodeAvailable":true,"isQuickSyncVP8EncodeAvailable":false,"isQuickSyncVP9EncodeAvailable":false,"isQuickSyncH264DecodeAvailable":true,"isQuickSyncH265DecodeAvailable":false,"isQuickSyncMP2DecodeAvailable":true,"isQuickSyncVP8DecodeAvailable":false,"isQuickSyncVP9DecodeAvailable":false},"infoVAAPI":{"available":false},"infoX264":{"available":false},"infoX265":{"available":false}}

                  

                   booleanavailable = false;

                   intcountGPU = 0;

 

                   StringjsonStr = transcoderContextServer.getHardwareInfoJSON();

                   if(jsonStr != null)

                   {

                            try

                            {

                                     JSONjsonData = new JSON(jsonStr);

                                                                          

                                     if(jsonData != null)

                                     {

                                               Map entries = jsonData.getEntrys();

                                              

                                               Map infoCUDA = (Map)entries.get("infoCUDA");

                                               if(infoCUDA != null)

                                               {

                                                       

                                                        ObjectavailableObj = infoCUDA.get("availabe");

                                                        if(availableObj != null && availableObj instanceof Boolean)

                                                        {

                                                                 available= ((Boolean)availableObj).booleanValue();

                                                        }

                                                       

                                                        if(available)

                                                        {

                                                                 ObjectcountGPUObj = infoCUDA.get("countGPU");

                                                                 if(countGPUObj != null && countGPUObj instanceof Integer)

                                                                 {

                                                                           countGPU= ((Integer)countGPUObj).intValue();

                                                                 }

                                                        }

                                               }

                                     }

                            }

                            catch(Exceptione)

                            {

                                     WMSLoggerFactory.getLogger(CLASS).info(CLASSNAME+".onHardwareInspection:Parsing JSON: ", e);

                            }

                   }

                                    

                   WMSLoggerFactory.getLogger(CLASS).info(CLASSNAME+".onHardwareInspection:CUDA available:"+available+" countGPU:"+countGPU);

 

                   synchronized(lock)

                   {

                            this.available= available;

                            this.countGPU= countGPU;

                           

                            if(this.countGPU > 1)

                            {

                                     this.gpuInfos= new GPUInfo[this.countGPU];

                                     for(inti=0;i

                                     {

                                               this.gpuInfos[i]= new GPUInfo();

                                              

                                               this.gpuInfos[i].gpuid= i;

                                              

                                               if(this.gpuWeights != null && i < this.gpuWeights.length)

                                                        this.gpuInfos[i].weight= this.gpuWeights[i];

                                               else

                                                        this.gpuInfos[i].weight= gpuWeightScale;

                                     }

                            }

                   }

         }

        

         @Override

         publicvoid onTranscoderSessionLoadBalance(LiveStreamTranscoder liveStreamTranscoder)

         {                

                   try

                   {

                            while(true)

                            {

                                     if(this.gpuInfos == null)

                                               break;

                                    

                                     TranscoderStreamtranscoderStream = liveStreamTranscoder.getTranscodingStream();

                                     if(transcoderStream == null)

                                               break;

                                    

                                     TranscoderSessiontranscoderSession = liveStreamTranscoder.getTranscodingSession();

                                     if(transcoderSession == null)

                                               break;

                                    

                                     TranscoderSessionVideotranscoderSessionVideo = transcoderSession.getSessionVideo();

                                     if(transcoderSessionVideo == null)

                                               break;

                                    

                                     MediaCodecInfoVideocodecInfoVideo = null;

                                     if(transcoderSessionVideo.getCodecInfo() != null)

                                               codecInfoVideo= transcoderSession.getSessionVideo().getCodecInfo();

 

                                     longloadDecode = 0;

                                     longloadScale = 0;

                                     longloadEncode = 0;

                                    

                                     booleanisScalerCUDA = false;

                                    

                                     TranscoderStreamSourceVideotranscoderStreamSourceVideo = null;

                                     TranscoderStreamScalertranscoderStreamScaler = null;

                                    

                                     TranscoderStreamSourcetranscoderStreamSource = transcoderStream.getSource();

                                     if(transcoderStreamSource != null)

                                     {

                                               transcoderStreamSourceVideo= transcoderStreamSource.getVideo();

                                               if(transcoderStreamSourceVideo != null && codecInfoVideo != null&& (transcoderStreamSourceVideo.isImplementationNVCUVID() ||transcoderStreamSourceVideo.isImplementationCUDA()))

                                               {

                                                        loadDecode= codecInfoVideo.getFrameWidth() * codecInfoVideo.getFrameHeight();

                                               }

                                               else

                                                        transcoderStreamSourceVideo= null;

                                     }

                                    

                                     transcoderStreamScaler= transcoderStream.getScaler();

                                     if(transcoderStreamScaler != null)

                                     {

                                               isScalerCUDA =transcoderStreamScaler.isImplementationCUDA();

                                     }

                                    

                                     Listdestinations = transcoderStream.getDestinations();

                                     if(destinations == null)

                                               break;

                                    

                                     for(TranscoderStreamDestinationdestination : destinations)

                                     {

                                               if(!destination.isEnable())

                                                        continue;

 

                                               TranscoderStreamDestinationVideodestinationVideo = destination.getVideo();

                                              

                                               if(destinationVideo == null)

                                                        continue;

                                              

                                               if(destinationVideo.isPassThrough() || destinationVideo.isDisable())

                                                        continue;

                                              

                                               TranscoderVideoFrameSizeHolderframeSizeHolder = destinationVideo.getFrameSizeHolder();

                                               if(frameSizeHolder == null)

                                                        continue;

                                              

                                               if(isScalerCUDA)

                                                        loadScale+= frameSizeHolder.getActualWidth() * frameSizeHolder.getActualHeight();

                                              

                                               if(destinationVideo.isImplementationNVENC() ||destinationVideo.isImplementationCUDA())

                                                        loadEncode+= frameSizeHolder.getActualWidth() * frameSizeHolder.getActualHeight();

                                     }

                                    

                                     longtotalLoad = (loadDecode*weightFactorDecode) + (loadScale*weightFactorScale) +(loadEncode*weightFactorEncode);

                                     if(totalLoad <= 0)

                                               break;

                                    

                                     totalLoad/= LOAD_MAG;

                                    

                                     if(totalLoad <= 0)

                                               totalLoad= 1;

                                    

                                     intgpuid = -1;

                                    

                                     synchronized(lock)

                                     {

                                               longleastLoad = Long.MAX_VALUE;

                                              

                                               for(inti=0;i

                                               {

                                                        if(gpuInfos[i].getWeightedLoad() < leastLoad)

                                                        {

                                                                 leastLoad= gpuInfos[i].getWeightedLoad();

                                                                 gpuid= i;

                                                        }

                                               }

                                              

                                               if(gpuid >= 0)

                                                        gpuInfos[gpuid].currentLoad+= totalLoad;

                                     }

 

                            WMSLoggerFactory.getLogger(CLASS).info(CLASSNAME+".onTranscoderSessionLoadBalance["+liveStreamTranscoder.getContextStr()+"]:gpuid:"+gpuid+" load:"+totalLoad+"[decode:"+loadDecode+" scale:"+loadScale+"encode:"+loadEncode+"]");

 

                                     if(gpuid >= 0)

                                     {

                                               liveStreamTranscoder.getProperties().put(PROPNAME_TRANSCODER_SESSION,new SessionInfo(gpuid, totalLoad));

 

                                               if(transcoderStreamSourceVideo != null)

                                                        transcoderStreamSourceVideo.setGPUID(gpuid);

                                              

                                               if(transcoderStreamScaler != null && isScalerCUDA)

                                                        transcoderStreamScaler.setGPUID(gpuid);

                                              

                                               for(TranscoderStreamDestinationdestination : destinations)

                                               {

                                                        if(!destination.isEnable())

                                                                 continue;

 

                                                        TranscoderStreamDestinationVideodestinationVideo = destination.getVideo();

                                                       

                                                        if(destinationVideo == null)

                                                                 continue;

                                                       

                                                        if(destinationVideo.isPassThrough() || destinationVideo.isDisable())

                                                                 continue;

                                                                                                                                                                       

                                                        if(destinationVideo.isImplementationNVENC() || destinationVideo.isImplementationCUDA())

                                                                 destinationVideo.setGPUID(gpuid);

                                               }

                                     }

                                     break;

                            }

                   }

                   catch(Exceptione)

                   {

                            WMSLoggerFactory.getLogger(CLASS).info(CLASSNAME+".onTranscoderSessionLoadBalance:Parsing JSON: ", e);

                   }

         }       

}


 

不同性能的多個(gè)GPU之間的負(fù)載均衡


這個(gè)內(nèi)建的TranscoderVideoLoadBalancerCUDASimple class 支持在不同性能的多個(gè)GPU之間實(shí)現(xiàn)負(fù)載均衡。你可以為每一個(gè)GPU設(shè)置不同的性能權(quán)重(或者叫負(fù)載權(quán)重,因?yàn)樾阅茉礁叩漠?dāng)然可以承擔(dān)更多的負(fù)載任務(wù))。 這個(gè)權(quán)重配置在transcoderVideoLoadBalancerCUDASimpleGPUWeights參數(shù)中。 

這個(gè)參數(shù)在一個(gè)列表中,用逗號(hào)分隔各個(gè)GPU的不同權(quán)重。我們建議你將性能最好的GPU的權(quán)重設(shè)置為100,然后其它性能低的GPU根據(jù)具體性能設(shè)置為對(duì)應(yīng)的百分比。 

對(duì)于這個(gè)列表中的GPU權(quán)重的順序,你可以在Wowza Streaming Engine的啟動(dòng)日志中看到,也就是說這里的順序和日志中顯示的GPU順序是一樣的。 例如,如果你的服務(wù)器上有一個(gè)M5000 卡 (順序 0) 和一個(gè) M2000 卡 (順序 1),那么在transcoderVideoLoadBalancerCUDASimpleGPUWeights中的權(quán)重可以按如下來配置: 

 

         transcoderVideoLoadBalancerCUDASimpleGPUWeights

         100,66

 

這表示了M2000卡的性能只有M5000卡性能的66%。 
 

Wowza Streaming Engine 4是業(yè)界功能強(qiáng)大、API接口豐富的流媒體Server產(chǎn)品,采用它作為流媒體服務(wù)器產(chǎn)品的案例很多,直播、在線教育、IPTV都有它的用武之地。

下一篇:Freshmarketer:快節(jié)奏團(tuán)隊(duì)的智能營(yíng)銷自動(dòng)化
上一篇:Wolfram創(chuàng)新獎(jiǎng)2015(五)

                               

 京ICP備09015132號(hào)-996 | 違法和不良信息舉報(bào)電話:4006561155

                                   © Copyright 2000-2026 北京哲想軟件有限公司版權(quán)所有 | 地址:北京市海淀區(qū)西三環(huán)北路50號(hào)豪柏大廈C2座11層1105室

                         北京哲想軟件集團(tuán)旗下網(wǎng)站:哲想軟件 | 哲想動(dòng)畫

                            華滋生物