CDN日誌實時分析
CDN(Content Delivery Network),內容分發網路)是網際網路網站、應用上極其重要的基礎設施,通過CDN,終端使用者可直接從邊緣節點訪問各種圖片、視訊資源,避免直接訪問源站。這對於降低訪問延時、提升體驗有很大幫助,也有助於源站降低負載,容應對流量高峰,保證服務的穩定。在(短)視訊、直播等對網路流量很大需求的領域,CDN作用尤其重要。
CDN對於網站、應用如此重要,對於CDN訪問的統計分析必不可少,先看一下以下幾個場景:
當前服務狀態是否正常
訪問PV、UV是否有波動
頻寬、訪問延時是否正常
快取命中率,訪問健康度如何
有人反饋服務訪問異常
異常來源是否有地域特性
是否和運營商有關
錯誤訪問和終端應用版本是否有關聯
流量上漲
是正常訪問還是攻擊
哪些是熱點資源
是否有異常客戶
是否由於客戶端快取策略導致
使用者行為分析
當前線上人數、訪問次數
熱門資源
訪問來源、agent、分佈等
傳統分析流程
現在各家CDN廠商,通常會提供基礎的監控指標,比如請求次數、頻寬等資訊,然後,在進行定製化分析場景下,預設指標往往不能解決所有問題,需要對原始日誌進行更深入的挖掘。以下是常見的處理方式:
定期下載CDN離線日誌
將資料匯入Hadoop 這樣的數倉系統
跑各類job(或hive)對資料進行分析,將最終結果匯入Mysql
對分析結果進行實時展示
對於報表場景,以上流程沒有太大問題,可以處理海量CDN的日誌,但是在實時問題定位,快速驗證、試錯等互動式分析強烈的場景下, 該方案的弊端就顯露出來:
離線模式下,資料產出實時性無法保證,延時從半小時到幾小時不等
需要維護多級Pipeline,需要有指令碼或工具將其串聯,有開發代價
環境維護,有運維代價,任意一個環節出問題,結果都不能產出
靈活性欠佳,無法快速響應實時互動查詢需求
針對這種情況, 阿里雲CDN和日誌服務進行了打通,CDN日誌可實時匯入日誌服務,使用SLS的查詢和SQL分析能力,來滿足使用者個性化、實時、互動式的分析需求:
CDN的訪問日誌,1分鐘內可投遞至日誌服務
直接在日誌服務控制檯進行SQL查詢,無需任何程式碼維護
秒級查詢分析1億~10億資料
使用日誌服務的Dashboard功能,制定靈活的報表
接下來,對於CDN資料各類分析需求,看看如何在日誌服務上實現。在這之前,我們先看一下CDN主要的欄位說明。
CDN日誌格式說明
欄位名字 | 型別 | 說明 |
---|---|---|
client_ip | text | 客戶端ip |
content_type | text | 資料型別 |
domain | text | 域名 |
hit_info | text | 快取命中資訊 HIT 或者 MISS |
method | text | 請求方法 |
refer_domain | text | 請求來源域名 |
refer_param | text | 請求來源url 引數 |
refer_uri | text | 請求來源uri |
remote_ip | text | remote ip |
remote_port | long | remote 埠 |
request_size | long | 請求輸入大小,單位byte |
request_time | long | 響應延時,單位毫秒 |
response_size | long | 請求返回大小,單位byte |
return_code | long | http 狀態碼 |
scheme | text | 請求協議, 如http |
uri | text | 請求uri |
uri_param | text | 請求引數 |
user_agent | text | 請求Agent資訊 |
uuid | text | 標識請求的唯一id |
xforwordfor | text | forword ip 地址 |
CDN質量和效能分析
CDN提供日誌中,包含了豐富的內容,我們可以從多個維度對CDN的整體質量和效能進行全方位的統計和分析
健康度
統計return_code小於500的請求佔所有請求的百分比
* | select sum(s) * 100.0/count(*) as health_ratio from (select case when return_code < 500 then 1 else 0 end as s from log)
快取命中率
統計return_code小於400的請求中, hit_info 為 HIT的請求百分比
return_code < 400 | select sum(s) * 100.0/count(*) as Hit_ratio from (select case when hit_info = 'HIT' then 1 else 0 end as s from log)
平均下載速度
統計一段時間內,總體下載量除以整體耗時獲得平均下載速度
* | select sum(response_size) * 1.0 /sum(request_time)
訪問次數Top域名
按照訪問域名次數進行Top排序
* | select Domain , count(*) as count group by Domain order by count desc limit 100
下載流量Top域名
按照各個域名下載資料量大小進行Top排序
* | select Domain , sum(response_size) as "下載總量" group by Domain order by "下載總量" desc limit 100
接下來,我們從省份和運營商的角度,來做實時統計:
各省訪問次數、下載流量、速度
使用ip_to_province函式,將client_ip轉化成對應的省份,統計各個省份的訪問次數,下載的總量,以及下載平均速度
* | select ip_to_province(client_ip) as province ,count(*) as "訪問次數", sum(response_size)/1024.0/1024.0/1024.0 as "下載流量(GB)" , sum(response_size) * 1.0 /sum(request_time) as "下載速度(KB/s)" group by province having ip_to_province(client_ip) != '' order by "下載流量(GB)" desc limit 200
運營商的下載次數、下載流量、速度
原理同上,使用ip_to_provider函式,將client_ip轉化成對應的運營商
* | select ip_to_provider(client_ip) as isp ,count(*) as "訪問次數", sum(response_size)/1024.0/1024.0/1024.0 as "下載流量(GB)" , sum(response_size) * 1.0 /sum(request_time) as "下載速度(KB/s)" group by isp having ip_to_provider(client_ip) != '' order by "下載流量(GB)" desc limit 200
請求響應延時
將訪問延時按照各視窗進行統計,可根據應用實際的情況來劃分合適的延時時間視窗
* | select case when request_time < 50 then '~50ms' when request_time < 100 then '50~100ms' when request_time < 200 then '100~200ms' when request_time < 500 then '200~500ms' when request_time < 5000 then '500~5000ms' else '5000ms~' end as latency , count(*) as count group by latency
訪問PV、UV統計
統計每分鐘內,訪問次數和獨立的client ip數
* | select date_format (from_unixtime(__time__ - __time__ % 60), '%H:%i') as date , count(*) as pv, approx_distinct(client_ip) as uv group by __time__ - __time__ % 60 order by __time__ - __time__ % 60
資料流量型別分佈
統計各資料型別的訪問分佈
* | select content_type , sum(response_size) as sum_res group by content_type order by sum_res desc limit 10
CDN錯誤診斷
訪問錯誤一直是影響服務體驗的重要一環,當出現錯誤的時候,需要快速定位當前錯誤QPS和比例是多少,哪些域名和URI影響最大,是否和地域、運營商有關,是不是釋出的新版本導致。
4xx、5xx錯誤百分比和分佈
根據return_code的值,將錯誤分為4xx和5xx兩類,從下面的錯誤百分比和分佈圖來看,主要的錯誤都是發生了403錯誤,說明被伺服器拒絕請求,這個時候就需要檢查是不是資源使用超過限制。
* | select date_format (from_unixtime(m_time), '%H:%i') as date, sum( ct ) * 100.0/max(total) as error_ratio , case when return_code/100 < 5 then '4xx' else '5xx' end as code from (select m_time, return_code, ct, (sum(ct) over(partition by m_time) ) as total from (select __time__ - __time__ % 60 as m_time, return_code , count(*) as ct from log group by m_time, return_code) ) group by m_time, return_code/100 having(return_code/100 >= 4) order by m_time limit 100000
return_code >= 400 | select return_code , count(*) as c group by return_code order by c desc
錯誤Top域名和Uri
對於return_code > 400的請求,按照域名和uri的維度進行top 排序
return_code > 400| select domain , count(*) as c group by domain order by c desc limit 10
return_code > 400| select uri , count(*) as c group by uri order by c desc limit 10
運營商和各省錯誤統計
return_code > 400 | select ip_to_provider(client_ip) as isp , count(*) as c group by isp having ip_to_provider(client_ip) != '' order by c desc limit 10
return_code > 400 | select ip_to_province(client_ip) as province , count(*) as c group by province order by c desc limit 50
錯誤詳情
對於錯誤資料,我們還可以從省份、運營商組合的角度來檢視錯誤的次數和百分比。
return_code >= 400 and return_code < 500 | select province as "省份", isp as "運營商", c as "錯誤次數", round(c * 100.0/ sum(c) over(), 2) as "錯誤比率(%)" from (select ip_to_province(client_ip) as province , ip_to_provider(client_ip) as isp , count(*) as c from log group by province, isp having(ip_to_provider(client_ip)) != '' order by c desc)
return_code >= 500 | select province as "省份", isp as "運營商", c as "錯誤次數", round(c * 100.0/ sum(c) over(), 2) as "錯誤比率(%)" from (select ip_to_province(client_ip) as province , ip_to_provider(client_ip) as isp , count(*) as c from log group by province, isp having(ip_to_provider(client_ip)) != '' order by c desc)
客戶端分佈
很多時候,錯誤的發生是由於新的版本釋出引入的bug,下圖中的例子,可以看到大部分錯誤都是出現在新發布的版本上,有這個維度的資訊後,問題調查的範圍可以大大縮小
return_code > 400 | select user_agent as "客戶端版本", count(*) as "錯誤次數" group by user_agent order by "錯誤次數" desc limit 10
使用者行為分析
基於CDN的訪問日誌,我們也可以對使用者的訪問行為進行分析, 如:
大部分使用者是從哪裡過來,是內部還是外部
哪些資源使用者是熱門資源
是否有使用者在瘋狂下載資源,行為是否符合預期
針對這些問題,我們舉例來說明,使用者也可以根據自己的業務場景進行定製化的分析
訪問來源統計
not refer_domain:"" | select refer_domain as "來源", c as "次數" , round(c * 100.0/(sum(c) over()) , 2) as "百分比%" from ( select refer_domain as refer_domain , count(*) as c from log group by refer_domain order by c desc limit 100 )
訪問Top uri
return_code < 400 | select uri ,count(*) as "訪問次數", round(sum(response_size)/1024.0/1024.0/1024.0, 2) as "下載總量(GB)" group by uri order by "訪問次數" desc limit 100
Top使用者統計
* | SELECT CASE WHEN ip_to_country(client_ip)='香港' THEN concat(client_ip, ' ( Hong Kong )') WHEN ip_to_province(client_ip)='' THEN concat(client_ip, ' ( Unknown IP )') WHEN ip_to_provider(client_ip)='內網IP' THEN concat(client_ip, ' ( Private IP )') ELSE concat(client_ip, ' ( ', ip_to_country(client_ip), '/', ip_to_province(client_ip), '/', if(ip_to_city(client_ip)='-1', 'Unknown city', ip_to_city(client_ip)), ' ',ip_to_provider(client_ip), ' )') END AS client, pv as "總訪問數", error_count as "錯誤訪問數" , throughput as "下載總量(GB)" from (select client_ip , count(*) as pv, round(sum(response_size)/1024.0/1024/1024.0, 1) AS throughput , sum(if(return_code > 400, 1, 0)) AS error_count from log group by client_ip order by throughput desc limit 100)
* | SELECT CASE WHEN ip_to_country(client_ip)='香港' THEN concat(client_ip, ' ( Hong Kong )') WHEN ip_to_province(client_ip)='' THEN concat(client_ip, ' ( Unknown IP )') WHEN ip_to_provider(client_ip)='內網IP' THEN concat(client_ip, ' ( Private IP )') ELSE concat(client_ip, ' ( ', ip_to_country(client_ip), '/', ip_to_province(client_ip), '/', if(ip_to_city(client_ip)='-1', 'Unknown city', ip_to_city(client_ip)), ' ',ip_to_provider(client_ip), ' )') END AS client, pv as "總訪問數", (pv - success_count) as "錯誤訪問數" , throughput as "下載總量(GB)" from (select client_ip , count(*) as pv, round(sum(response_size)/1024.0/1024/1024.0, 1) AS throughput , sum(if(return_code < 400, 1, 0)) AS success_count from log group by client_ip order by success_count desc limit 100)
後續
阿里雲CDN和日誌服務打通之後,依託CDN強大的資料分發能力,和日誌服務靈活、快捷的統計分析能力,使用者對於CDN的資料分析將變得極其簡單和方便。現在CDN底層日誌已經能匯入日誌服務,產品上的打通也在進行中,預計8月份使用者可以直接在CDN控制檯上開通使用。
公眾號推薦:
相關文章
- 日誌實時分析:從入門到精通
- 實時日誌分析系統的基本架構架構
- 日誌分析-apache日誌分析Apache
- 虎牙數萬主播同時線上直播的祕密,CDN推流日誌上行實時監控
- ELK實時分析之php的laravel專案日誌PHPLaravel
- ELK實時日誌分析平臺環境部署--完整記錄
- [日誌分析篇]-利用ELK分析jumpserver日誌-日誌拆分篇Server
- 解鎖Nginx日誌的寶藏:GoAccess——你的實時、互動式Web日誌分析神器!NginxGoWeb
- 雲盾.態勢感知-實時日誌分析平臺上線
- ELK(ElasticSearch, Logstash, Kibana)搭建實時日誌分析平臺Elasticsearch
- 實戰案例:醫療臨床大資料實時流日誌分析大資料
- 實時檢視tomcat日誌Tomcat
- 玄機-第二章日誌分析-apache日誌分析Apache
- Apche日誌系列(4):日誌分析(轉)
- Flume 實現自己的實時日誌(2)
- Kafka實戰-實時日誌統計流程Kafka
- FDOAGENT日誌分析
- crash日誌分析
- awk分析日誌
- pg日誌分析
- 分析24小時日誌獲取交易時間分佈
- Java實時讀取日誌檔案Java
- 實時備份mysql binlog日誌MySql
- Nginx 訪問日誌實時解析 ngxtopNginx
- 網際網路大資料日誌收集離線實時分析實戰案例大資料
- 日誌易:IT運維分析及海量日誌搜尋的實踐之路(上)運維
- Docker 容器日誌分析Docker
- JAVA GC日誌分析JavaGC
- perl分析apache日誌Apache
- 日誌收集分析-heka
- awstats分析web日誌Web
- mysqldumpslow日誌分析MySql
- LOGMINER日誌分析
- 日誌採集/分析
- Logminer簡單分析日誌的實驗
- linux-實現日誌分析--pythonLinuxPython
- 日誌和實時流計算處理
- 行為、審計日誌(實時索引/實時搜尋)-最佳實踐索引