zoukankan      html  css  js  c++  java
  • 在没Hadoop 、GP 前提下怎么进行实时数据统计。

        最近着手个项目,整体数据量有5亿多,每个月增量9000w。应用场景是Oltp 根据用户id直接计算各种维度值。

    因为是Oltp 场景,直接根据用户id %2000分(方便后续横向扩展),有些喜欢扯分区表的或者顺序分表的请复习下数据库原理以及硬件原理。

    分完表oltp 访问速度上了几个level。但是牵涉到一个实时统计的问题,需要对2000张表进行实时统计。因暂时没gp、hadoop 这种分布式数据库环境,以及怎么解决Oltp 到分布式数据库之间实时同步的问题。

    想了个恶心的办法。对2000张表开启cdc 变更,记录时间段发生的变更userid,写了个多线程脚本实时根据这些userid 去更新数据。基本做到了实时统计,数据时间间隔差10分钟左右。

    明年计划结构化数据先通过Gp计算,需要写个小程序来满足Cdc 变更到Gp的实时同步。 

       

     顺便附带 多线程统计脚本,还是powershell 写的。

    #region hostinfo
    $hostinfos=[System.Collections.ArrayList]@()
    [void] $hostinfos.add('192.168.1.1')
    [void] $hostinfos.add('1433')
    [void] $hostinfos.add( $ClientSqlAccount)
    [void] $hostinfos.add($ClientSqlPassWord)
    [void] $hostinfos.add('db')
    #endregion
    
    #region 生成2000张表
    $tables=[System.Collections.ArrayList]@()
    <#
    foreach($s in 0..1999)
    {
        switch([void] $s)
        {
          {$s -lt 10 }{ [void] $tables.add('Tab'+'000'+ $s.ToString());}
          {$s -ge 10 -and $s -lt 100 }{ [void] $tables.add(('Tab'+'00'+ $s.ToString()));  }
          {$s -ge 100 -and $s-lt 1000 }{ [void] $tables.add(('Tab'+'0'+ $s.ToString()));  }
          {$s -ge 1000  }{  [void] ($tables.add(('Tab'+ $s.ToString()))); }
        }
    
    }
    #>
    #endregion
    
        $ClientSqlAccount=$hostinfos[2];
        $ClientSqlPassWord=$hostinfos[3];
        $ClientDB=$hostinfos[4];
        $log='d:'
        $SqlServer=$hostinfos[0]  ;
        $Port=$hostinfos[1] ;
        $SqlString="Data Source="+$SqlServer+","+$Port+";uid="+$ClientSqlAccount+";Password="+$ClientSqlPassWord;
        $SqlConn = [System.Data.SqlClient.SqlConnection] $SqlString;
        $SqlConn.Open() ;
        $SqlConn.ChangeDatabase($ClientDB);
        $CC = $SqlConn.CreateCommand();
        $CC.CommandTimeout = 0;
        $CC.CommandText='select tabname  from Cdc_Change_userid where isdelete=0 group by tabname '
        $Reader = $CC.ExecuteReader();
        while ($Reader.read())
         { 
            [void] $tables.add($Reader.GetString(0)); 
         }
        $SqlConn.Close();
    
    
    #region Get SqlserverObjectScriptBlock
      $SBbillcellphone={
        param($hostinfos,$sqlcmd) 
        Function Sqler_BillCellPhones
        {param(
             [array] $hostinfos
            ,[string] $sqlcmd
           )
            try
            {
                   $ClientSqlAccount=$hostinfos[2];
                   $ClientSqlPassWord=$hostinfos[3];
                   $ClientDB=$hostinfos[4];
                   $log='d:'
                   $SqlServer=$hostinfos[0]  ;
                   $Port=$hostinfos[1] ;
                   $SqlString="Data Source="+$SqlServer+","+$Port+";uid="+$ClientSqlAccount+";Password="+$ClientSqlPassWord;
                   $SqlConn = [System.Data.SqlClient.SqlConnection] $SqlString;
                   $SqlConn.Open() ;
                   $SqlConn.ChangeDatabase($ClientDB);
                   $CC = $SqlConn.CreateCommand();
                   $CC.CommandTimeout = 0;
                   $CC.CommandText=$sqlcmd
                   $CC.ExecuteScalar();
                   $SqlConn.Close();
            }
            catch
            {
    
               $day=(Get-Date -Format "yyyyMMdd").tostring();
               $return='Error';
               ( 'Sqler_BillCellPhones  : '+((Get-Date).tostring())+' '+ $SqlServer+','+$Port +' '+$_.Exception.Message )|Out-File  -FilePath  "$log	ab_$day.log"   -Append -Force
    
            }
        }
        Sqler_BillCellPhones $hostinfos $sqlcmd
     }
    
        $throttleLimit=5
        $sqlcmd='exec csp_billcellphone_Score ''@tabname''';
        $SessionState = [system.management.automation.runspaces.initialsessionstate]::CreateDefault()
        $Pool = [runspacefactory]::CreateRunspacePool(1, $throttleLimit, $SessionState, $Host)
        $Pool.Open()
        $threads = @() 
        $handles = foreach($table in $tables) { 
            $sqlcmd='exec csp_billcellphone_Score ''@tabname''';
            $sqlcmd=$sqlcmd-replace '@tabname',$table
            $powershell = [powershell]::Create().AddScript($SBbillcellphone).AddArgument($hostinfos).AddArgument($sqlcmd)
            $powershell.RunspacePool = $Pool
            $powershell.BeginInvoke()
          $threads += $powershell
        }
        do {
          $i = 0
          $done = $true
          foreach ($handle in $handles) {
            if ($handle -ne $null) {
              if ($handle.IsCompleted) {
                $threads[$i].EndInvoke($handle)
                $threads[$i].Dispose()
                $handles[$i] = $null
              } else {
                $done = $false
              }
            }
            $i++
          }
          if (-not $done) { Start-Sleep -second 1 }
        } until ($done)
     Remove-Variable -Name handles, threads,powershell;
     [System.GC]::Collect(); [System.GC]::WaitForPendingFinalizers()
  • 相关阅读:
    iOS $299刀企业证书申请的过程以及细节补充
    关于移动开发的一些想法和认识--Android和iOS
    iOS设备的越狱方法
    iOS越狱开发(一)
    iOS开发中 workspace 与 static lib 工程的联合使用
    高效 Java Web 开发框架 JessMA v3.5.1
    跨平台日志清理工具 Log-Cutter v2.0.1 正式发布
    【新年呈献】高性能网络通信框架 HP-Socket v5.7.1
    高性能网络通信框架 HP-Socket v5.2.1
    跨年呈献:HP-Socket for Linux 1.0 震撼发布
  • 原文地址:https://www.cnblogs.com/xwj1985/p/4098620.html
Copyright © 2011-2022 走看看