原文地址:http://cyr520.blog.51cto.com/714067/1209485
scribe簡介
Scribe是Facebook開源的分佈式日誌收集系統,目前在各大互聯網公司內部已經得到大量的應用。它能夠從各種日誌源上收集日誌,存儲到一箇中央存儲系統(可以是NFS,分佈式文件系統等)上,以便於進行集中統計分析處理。
它爲日誌的“分佈式收集,統一處理”提供了一個可擴展的,高容錯的方案。當中央存儲系統的網絡或者機器出現故障時,scribe會將日誌轉存到本地或者另一個位置,當中央存儲系統恢復後,scribe會將轉存的日誌重新傳輸給中央存儲系統。其通常與Hadoop結合使用,scribe用於向HDFS中push日誌,而Hadoop通過MapReduce作業進行定期處理。
系統架構
常見部署結構:
準備工作
1 | yum -y install gcc gcc-c++ m4 autoconf automake libtool libicu-devel python-devel libevent-devel flex |
刷新動態鏈接庫:
1 | /sbin/ldconfig |
下載安裝包:
1 2 3 4 5 | mkdir -p /data/software cd /data/software/ wget http: //sourceforge .net /projects/boost/files/boost/1 .44.0 /boost_1_44_0 . tar .gz /download wget http: //archive .apache.org /dist/incubator/thrift/0 .4.0-incubating /thrift-0 .4.0. tar .gz wget https: //github .com /downloads/facebook/scribe/scribe-2 .1. tar .gz --no-check-certificate |
注意:github上使用wget下載程序,需要使用指定--no-check-certificate參數。
編譯安裝boost:
1 2 3 4 5 6 7 8 | cd /data/software/ tar zxvf boost_1_44_0. tar .gz cd boost_1_44_0 . /bootstrap .sh --prefix= /usr/local/boost . /bjam --prefix= /usr/local/boost install echo "/usr/local/boost/lib/" >> /etc/ld .so.conf
|
編譯安裝thrift:
thrift需要python支持distutils.core,如果看到的不是OK,請升級python-devel到更高版本。
1 2 3 4 5 6 7 8 | cd /data/software/ tar zxvf thrift-0.4.0. tar .gz cd thrift-0.4.0 . /configure --prefix= /usr/local/thrift --with-csharp=no --with-java=no --with-erlang=no --with-perl=no --with-php=yes --with-ruby=no --with-py= yes --with-libevent --with-boost= /usr/local/boost/ make make install echo "/usr/local/thrift/lib/" >> /etc/ld .so.conf /sbin/ldconfig |
編譯安裝thrift-fb303:
1 2 3 4 5 | cd /data/software/thrift-0 .4.0 /contrib/fb303/ . /bootstrap .sh --with-boost= /usr/local/boost/ . /configure --prefix= /usr/local/fb303 --with-boost= /usr/local/boost/ --with-thriftpath= /usr/local/thrift/ make make install |
安裝scribe
編譯安裝:
1 2 3 4 5 6 | cd /data/software/ tar zxvf scribe-2.1. tar .gz cd scribe-2.1
make
### 在把lib加到裏面,不然在啓動的時候會報錯#####
|
瞭解配置文件
Scribe的配置文件分爲全局配置和存儲配置兩部分:
全局配置項
port:指示scribe服務器在哪一個端口上監聽,默認是0,通過命令行參數選項-P可以指定端口,也能夠通過配置文件指定。在源代碼中就賦值給變量port。
max_msg_per_second:默認值是0,如果這個參數值是0將被忽略。隨着最近的改變這個參數很少被關聯使用到,max_queue_size參數將被應用到限制每秒最大的消息數。在scribeHandler::throttleDeny被使用。
max_queue_size(按字節):接收消息的隊列的最大字節,默認是5,000,000字節。在scribeHandler::Log使用。
check_interval(秒):用於控制多長時間檢查一次存儲,默認值是5.
new_thread_per_category(是/否):如果爲是,將爲每一個分類場景創建一個新的線程,否則將創一個單線程爲每一個在配置文件中定義的存儲。對於前綴存儲或默認存儲,如果這個參數設置成“否”將導致所有匹配這個分類的消息都由一個單獨的存儲來處理。否則將爲每一個唯一的分類名創建一個新的存儲。默認爲“是”。
num_thrift_server_threads:爲接收消息的監聽線程數量,默認是3.
max_conn:最大的鏈接數。
存儲配置
Scribe服務器決定怎樣將日誌消息寫入是基於在配置中定義的存儲類型和相關參數設置,每一個存儲都必須指定一個消息分類來處理三種異常。
默認存儲:默認分類處理任何不能被其他存儲處理的分類,這兒僅僅能夠有一個默認存儲。
前綴存儲:如果指定分類以一個*結尾,這個存儲將處理所有以指定前綴開頭的分類。
多個類別:在一個存儲定義中能夠使用‘categories=’創建多個類別。
在上面三種情況下,在文件存儲中將爲每一個唯一的分類創建一個子目錄(除非new_thread_per_category被設置爲false)。
存儲配置變量
category:決定哪些消息被這個存儲處理。
type:存儲類型,有file、buffer、network、bucket、thriftfile、null、mutil。
target_write_size:默認是16,384字節,決定在這些消息處理之前在給定分類的消息隊列可以增長到多大。
max_batch_size: 默認1,024,000字節(可能沒有被開源),決定在內存存儲隊列中一次能夠被處理的數據的總數,這個(加上緩衝文件旋轉的大小)控制多大的一個thrift調用可行。
max_write_interval:默認是10秒,決定在這些消息處理之前在給定分類的消息隊列可以用多長時間。
must_succeed(yes/no):是否必須成功,如果一個存儲處理消息失敗是否重新進入消息隊列排隊,如果設置成 ‘no’,且一個存儲不能處理這些消息,消息將被丟棄。默認是yes。強烈建議使用緩存來指一個定二級存儲來處理失敗的日誌。
存儲類型
file存儲配置
File存儲寫入消息到一個文件。
file_path:文件路徑,默認是“/tmp”。
base_filename:基本文件名稱,默認是分類名稱。
use_hostname_sub_directory(yes/no):使用服務器的主機名創建一個子目錄,默認是no。
sub_directory:使用指定的名稱創建一個子目錄。
rotate_period:文件創建週期,取值可以是 “hourly”, “daily”, “never”,或者是name[後綴], “never”是默認值,決定多長時間創建一個新文件,特別的後綴“s”, “m”, “h”, “d”, “w”分別代表second(默認)、minutes、hours、days和weeks。
rotate_hour:取值0-23,默認是1,如果rotate_period取值是daily,這個就決定每天的什麼時候創建新文件。
rotate_minute:取值0-59,默認是15,如果rotate_period設置爲daily或hourly,這個就決定以一個小時過後多久創建一個新文件。
max_size:文件上限大小,默認1,000,000,000多字節,決定在輪流創建一個新文件以前一個文件能夠增長到多大。
write_meta:取值yes或其他任何,false爲默認值,如果文件被旋轉,最後一行將包含“scribe_meta”,跟着就是下一個文件名。
fs_type:文件類型,支持“std”和“hdfs”兩種格式,“std”爲默認值。
chunk_size:默認值是0,如果一個塊大小被指定,在文件內沒有消息能夠跨越塊的邊界,除非有消息的大小超過塊的大小。
add_newlines:取值0或1,默認是0,如果設置爲1,以後的每一個消息都寫入一個新行。
create_symlink:yes或其他任何,默認是yes。如果爲yes,將保持一個符號鏈接指向最近一個被寫入的文件。
write_stats:yes/no,默認是yes。是否創建一個scribe_stats文件爲每一個存儲來保持文件寫入的軌跡。
max_write_size:默認是1000000字節。File存儲將嘗試按max_write_size字節的塊大小刷新數據到文件系統。max_write_size的大小不能超過max_size。由於target_write_size一定數量的消息被緩存。那麼文件存儲被調用來保持這些消息。File_store以一次性至少max_write_size大小字節的塊來保存這些消息。File存儲的最後一次寫入比max_write_size小;
write_category:寫入一個分類下面;
rotate_on_reopen:循環重新打開。
network存儲配置
Network存儲向其他scribe服務器發送消息。Scribe保持持久的鏈接打開以至於它能夠發送消息。(爲了錯誤信息或者如果下游機器過載,它將重新打開一個鏈接)。在正常運行的情況下,scribe會基於當前緩存中存在多少條消息等待發送而分批次的發送。(如果scribe備份和緩存消息到本地磁盤,scribe會基於緩存文件大小按塊發送消息)
remote_host:發送消息的遠程主機的名稱或IP地址。
remote_port:在遠程主機上的端口。
timeout:socket超時,MS爲單位,默認是DEFAULT_SOCKET_TIMEOUT_MS, 在store.h中被設置爲5000。
use_conn_pool:yes或者任何其他,默認是false。是否使用連接池代替爲每一個遠程主機打開的鏈接。
smc_service:
service_options:
service_cache_timeout:
ignore_network_error:
dynamic_config_type:
buffer存儲配置
這是最常用的一種store。該store中包含兩個子store,其中一個是primary store,另一個是secondary store。日誌會優先寫到primary store中,如果primary store出現故障,則scribe會將日誌暫存到secondary store中,待primary store恢復性能後,再將secondary store中的數據拷貝到primary store中。其中,secondary store僅支持兩種store,一個是file,另一個是null。
max_queue_length:默認2,000,000條消息。如果在隊列中的消息數量超過了這個值,buffer存儲將切換寫入secondary store。
buffer_send_rate:默認值是1。決定每一次check_interval內,多少次從secondary store讀出一組消息並且發送到primary store中。
retry_interval:默認是300秒。在寫primary store失敗以後等待多長時間重新發送到primary store。
retry_interval_range:默認是60秒。將在指定retry_interval區間內隨機的選擇一個重新發送時間區間。
replay_buffer:取值yes/no,默認是yes。如果設置爲 ‘no’,buffer存儲不能從secondary store移除消息並且發送到primary store中去。
bucket存儲配置
Bucket存儲使用每個帶前綴的消息作爲key寫入到多個文件中去。能夠定義一個隱藏的或明確的bucket。定義隱藏的bucket必須要有一個名稱是 “bucket” 子bucket,這個子bucket可以是file存儲、network存儲或者thriftfile存儲。
num_buckets:hash進入的bucket個數,默認是1。不能被hash進入任何bucket的消息將被放入一個特別的0號bucket。
bucket_type: 取值是“key_hash”, “key_modulo”, 或者 “random”。
delimiter:必須是1-255之間的ascii代碼,否則默認是 ‘:’。第一次出現在消息前綴中的delimiter在‘hash/modulo’中將被用作key。Random不使用這個delimiter。
remove_key:取值yes/no,默認是是no。是否從消息中移除key前綴。
bucket_subdir:如果使用的是一個單獨定義的bucket,每一個子目錄的名稱根據bucket的數量編號生成。
null存儲配置
忽略被給分類的所有消息。沒有參數。
mutil存儲配置
一個mutil存儲是將所有消息轉發到子存儲中去的一個存儲。一個mutil存儲可能有多個名叫“store0”, “store1”, “store2”等等的子存儲。
report_success:取值 “all” or “any”, 默認是 “all”。是否所有substores或任何substores必須成功地記錄消息,以報告爲成功的消息記錄在日誌消息
thriftfile存儲配置
Thriftfile存儲類似於file存儲,出了thriftfile存儲是用Thrift TFileTransport file存儲消息。
file_path:文件路徑,默認是“/tmp”。
base_filename:基本文件名稱,默認是分類名稱。
rotate_period:文件創建週期,取值可以是 “hourly”, “daily”, “never”,或者是name[後綴], “never”是默認值,決定多長時間創建一個新文件,特別的後綴“s”, “m”, “h”, “d”, “w”分別代表second(默認)、minutes、hours、days和weeks。
rotate_hour:取值0-23,默認是1,如果rotate_period取值是daily,這個就決定每天的什麼時候創建新文件。
rotate_minute:取值0-59,默認是15,如果rotate_period設置爲daily或hourly,這個就決定以一個小時過後多久創建一個新文件。
max_size:文件上限大小,默認1,000,000,000多字節,決定在輪流創建一個新文件以前一個文件能夠增長到多大。
fs_type:文件類型,當前只支持“std”,“std”爲默認值。
chunk_size:默認值是0,如果一個塊大小被指定,在文件內沒有消息能夠跨越塊的邊界,除非有消息的大小超過塊的大小。
create_symlink:yes或其他任何,默認是yes。如果爲yes,將保持一個符號鏈接指向最近一個被寫入的文件。
flush_frequency_ms:毫秒單位,如果沒有指定就使用默認300的 TFileTransport。決定一步到thrift file磁盤時間的頻率。
msg_buffer_size:以字節爲單位,如果沒有指定將使用默認爲0的TFileTransport。如果非零,將拒絕寫入比這個值大的。
配置實例
1 2 3 4 | mkdir -p /usr/local/scribe/conf (存放起服腳本、測試工具和配置文件) mkdir -p /usr/local/scribe/logs (存放日誌文件) mkdir -p /usr/local/scribe/data (存放數據文件) cd /usr/local/scribe/conf/ |
編輯啓動scribe服務端腳本
1 | vim start_scribe_service.sh |
123#!/bin/sh
export
LANG=de_DE.UTF-8
/usr/local/scribe/bin/scribed
/usr/local/scribe/conf/scribe_service
.conf 1>
/usr/local/scribe/logs/scribe_service
.log 2>&1 &
編輯scribe服務配置文件
1 | vim scribe_service.conf |
123456789101112131415161718192021222324port=1463
max_msg_per_second=2000000
check_interval=3
<store>
category=default
type
=buffer
target_write_size=20480
max_write_interval=1
buffer_send_rate=1
retry_interval=30
retry_interval_range=10
<primary>
type
=network
remote_host=192.168.1.25
remote_port=1463
<
/primary
>
<secondary>
type
=
file
fs_type=std
file_path=
/data/scribe/data
base_filename=log
max_size=3000000
<
/secondary
>
<
/store
>
編輯scribe_ctrl工具
1 | vim scribe_ctrl |
12345678910111213141516171819202122#!/usr/bin/env python
import
sys
from fb303_scripts
import
*
# thrift python packages need to be installed
import
thrift
from thrift
import
protocol, transport
from thrift.transport
import
TTransport
from thrift.protocol
import
TBinaryProtocol
if
(len(sys.argv) > 2):
port = int(sys.argv[2])
else
:
port = 1463
if
(len(sys.argv) > 1):
retval = fb303_simple_mgmt.service_ctrl(sys.argv[1],
port,
trans_factory = TTransport.TFramedTransportFactory(),
prot_factory = TBinaryProtocol.TBinaryProtocolFactory())
sys.
exit
(retval)
else
:
'Usage: scribe_ctrl command [port]'
' commands: stop counters status version name alive'
sys.
exit
(2)
編輯測試工具
1 | vim scribe_cat |
12345678910111213141516171819202122232425262728293031323334#!/usr/bin/python
import
sys
from scribe
import
scribe
from thrift.transport
import
TTransport, TSocket
from thrift.protocol
import
TBinaryProtocol
if
len(sys.argv) == 2:
category = sys.argv[1]
host =
'127.0.0.1'
port = 1463
elif
len(sys.argv) == 4 and sys.argv[1] ==
'-h'
:
category = sys.argv[3]
host_port = sys.argv[2].
split
(
':'
)
host = host_port[0]
if
len(host_port) > 1:
port = int(host_port[1])
else
:
port = 1463
else
:
sys.
exit
(
'usage (message is stdin): scribe_cat [-h host[:port]] category'
)
log_entry = scribe.LogEntry(dict(category=category, message=sys.stdin.
read
()))
socket = TSocket.TSocket(host=host, port=port)
transport = TTransport.TFramedTransport(socket)
protocol = TBinaryProtocol.TBinaryProtocol(trans=transport, strictRead=False, strictWrite=False)
client = scribe.Client(iprot=protocol, oprot=protocol)
transport.
open
()
result = client.Log(messages=[log_entry])
transport.close()
if
result == scribe.ResultCode.OK:
sys.
exit
()
elif
result == scribe.ResultCode.TRY_LATER:
print >> sys.stderr,
"TRY_LATER"
sys.
exit
(84)
# 'T'
else
:
sys.
exit
(
"Unknown error code."
)
給予執行權限
1 2 3 | chmod +x start_scribe_service.sh chmod +x scribe_ctrl chmod +x scribe_cat |
啓動scribe服務
1 | . /start_scribe_service .sh |
查看服務啓動端口情況
1 | netstat -nutpl | grep 1463 |
查看服務器日誌
1 | tail -f scribe_service.log |
控制工具:
1 | cd /usr/local/scribe/conf/ |
使用方法:
1 | scribe_ctrl command [port] |
可用命令參數如下:
status – 如果服務器運行正常則返回'ALIVE'
version – 返回當前Scribe服務器的版本、
alive – 返回服務器運行時間
stop – 停止Scribe服務器
reload – 重新加載Scribe配置文件
counters – 返回下列統計信息 (如果非零):
received good: 返回Scribe服務器啓動後接收到的信息數
received bad: 接收到的非法信息數
sent:發送到另一臺Scribe服務器的信息數
denied for queue size: 因信息隊列滿被禁止的請求數
denied for rate: 由於速度限制而被禁止的請求數
retries: 緩衝儲存重試發送一批消息的次數
requeue: Scribe發送消息到一個Store的次數 (如果must_succeed 啓用).
lost: 沒有記錄的消息的數量。(推薦配置: 使用Buffer Stores 避免信息丟失)
received blank category: 接收到的沒有信息類別的信息數量
使用方法圖示如下:
測試scribe功能
測試命令如下:
1 2 3 | cd /usr/local/scribe/conf/ echo "hello world" | . /scribe_cat test cd /usr/local/scribe/data/ |
測試結果圖示如下:
到這裏,scribe的安裝和配置方法基本上就完整了。如果大家有問題請和我溝通。^_^
關於如何將scribe運用到業務當中,請移步:http://cyr520.blog.51cto.com/714067/1265181
本文出自 “小崔的成長之路” 博客,請務必保留此出處http://cyr520.blog.51cto.com/714067/1209485