Facebook Scribe介绍

1. 介绍

            Scribe是Facebook一个开源的实时分布式日志收集系统。它提高了大规模日志收集的可靠性和可扩展性。你可以在不同的节点上安装Scribe服务,然后这些服务会把收集到的信息发布到中心的服务集群上去。当中心服务不可得到时,本地的Scribe服务会暂时把收集到的信息存储到本地,等中心服务恢复以后再进行信息的上传。中心服务集群可以把收集到的信息写入本地磁盘或者分布式文件系统上,如hdfs,或者分发到另一层的Scribe服务集群上去。

 

Scribe提供了一种无阻塞的thrift服务,底层依赖libevent库和thrift库的支持。

 

2. 安装

        安装的方法在https://github.com/facebook/scribe可以找到,这里提几点注意的,第一是要注意一些依赖库的安装,特别是thrift的fb303,它提供了对thrift服务的监控与动态配置等操作。在thrfit源代码的contrib中可以找到,安装方法与安装thrift一样。第二个就是如果你安装好了Scribe,在运行其中的例子的时候会出来python的模块找不到,注意要配置一下PYTHONPATH这个环境变量。

 

3. 例子

在Scribe的源代码包中有examples这个目录,其中有三个例子。

第一个是简单的如何启动Scribe服务与发送消息给Scribe服务。

 

[c-sharp] view plaincopy
  1. #Create a directory to log messages:  
  2. mkdir /tmp/scribetest  
  3. #Start scribe using the configuration in example1.conf:  
  4. src/scribed examples/example1.conf  
  5. #From another terminal, use scribe_cat to send a message to scribe:  
  6. echo "hello world" | ./scribe_cat test  
  7. #If the previous command failed, make sure you did a 'make install' from the  
  8. #root scribe directory and that $PYTHONPATH is set correctly(see README.BUILD)  
  9. #Verify that the message got logged:  
  10. cat /tmp/scribetest/test/test_current  
  11. #Check the status of scribe (requires root):  
  12. ./scribe_ctrl status  
  13. #Check scribe's counters (you should see 1 message 'received good'):  
  14. ./scribe_ctrl counters  
  15. #Shutdown scribe:  
  16. ./scribe_ctrl stop  

 

 

 

第二个例子是如何在多个Scribe实例上进行消息的传递。

 

[c-sharp] view plaincopy
  1. # This example shows you how to log messages between multiple Scribe instances.  
  2. # In this example, we will run each Scribe server on a different port to simulate  
  3. # running Scribe on multiple machines.  
  4.           'client'                    'central'  
  5. ----------------------------     --------------------  
  6. | Port 1464                 |    | Port 1463         |  
  7. |        ----------------   |    | ----------------  |  
  8. |     -> | scribe server |--|--->| | scribe server | |  
  9. |        ----------------   |    | ----------------  |  
  10. |                |          |    |    |         |    |  
  11. |            temp file      |    |    |    temp file |  
  12. |---------------------------     |-------------------  
  13.                                       |  
  14.                                    -------------------  
  15.                                    | /tmp/scribetest/ |  
  16.                                    -------------------  
  17.  
  18. #Create a directory for the second scribe instance:  
  19. mkdir /tmp/scribetest2  
  20. #Start up the 'central' instance of Scribe on port 1463 to write messages to disk  
  21. #(See example2central.conf):  
  22. src/scribed examples/example2central.conf  
  23. #Start up the 'client' instance of Scribe on port 1464 to forward messages to  
  24. #the 'central' Scribe server (See example2client.conf):  
  25. src/scribed examples/example2client.conf  
  26. #Use scribe_cat to send some messages to the 'client' Scribe instance:  
  27. echo "test message" | ./scribe_cat -h localhost:1464 test2  
  28. echo "this message will be ignored" | ./scribe_cat -h localhost:1464 ignore_me  
  29. echo "123:this message will be bucketed" | ./scribe_cat -h localhost:1464 bucket_me  
  30. #The first message will be logged similar to example 1.  
  31. #The second message will not get logged.  
  32. #The third message will be bucketized into 1 of 5 buckets  
  33. #(See example2central.conf)  
  34. #Verify that the first message got logged:  
  35. cat /tmp/scribetest/test2/test2_current  
  36. #Verify that the third message got logged into a subdirectory:  
  37. cat /tmp/scribetest/bucket*/bucket_me_current  
  38. #Check the status and counters of both instances:  
  39. ./scribe_ctrl status 1463  
  40. ./scribe_ctrl status 1464  
  41. ./scribe_ctrl counters 1463  
  42. ./scribe_ctrl counters 1464  
  43. #Shutdown both servers:  
  44. ./scribe_ctrl stop 1463  
  45. ./scribe_ctrl stop 1464  
  46. ./scribe_ctrl stop  

 

 

第三个例子是当中心服务关闭以后,看本地的Scribe的一个缓冲反应。

 

[c-sharp] view plaincopy
  1. # Test Scribe buffering  
  2. #Startup the two Scribe instances used in Example 2.  
  3. #Start the 'central' server first:  
  4. src/scribed examples/example2central.conf  
  5. #Then start the 'client':  
  6. src/scribed examples/example2client.conf  
  7. #Log a message to the 'client' Scribe instance:  
  8. echo "test message 1" | ./scribe_cat -h localhost:1464 test3  
  9. #Verify that the message got logged:  
  10. cat /tmp/scribetest/test3/test3_current  
  11. #Stop the 'central' Scribe instance:  
  12. ./scribe_ctrl stop 1463  
  13. #Attempting to check the status of this server will return failure since it not running:  
  14. ./scribe_ctrl status 1463  
  15. #Try to Log another message:  
  16. echo "test message 2" | ./scribe_cat -h localhost:1464 test3  
  17. #This message will be buffered by the 'client' since it cannot be forwarded to  
  18. #the 'central' server.  Scribe will keep retrying until it is able to send.  
  19. #After a couple seconds, the status of the 'client' will be set to a warning message:  
  20. ./scribe_ctrl status 1464  
  21. #Try to Log yet another message(which will also get buffered):  
  22. echo "test message 3" | ./scribe_cat -h localhost:1464 test3  
  23. #Restart the 'central' instance:  
  24. src/scribed examples/example2central.conf  
  25. #Wait for both Scribe instance's statuses to change to ALIVE:  
  26. ./scribe_ctrl status 1463  
  27. ./scribe_ctrl status 1464  
  28. #Verify that all 3 messages have now been received by the 'central' server:  
  29. cat /tmp/scribetest/test3/test3_current  
  30. #Shutdown:  
  31. ./scribe_ctrl stop 1463  
  32. ./scribe_ctrl stop 1464  

 

 

 

由于没有找到c++的例子,这里自己写了一个简单的例子,仅供参考

 

  1. #include <iostream>  
  2. // scribe headers  
  3. #include "scribe.h" // this header is in the gen-cpp directory  
  4. // thrift headers  
  5. #include <protocol/TBinaryProtocol.h>  
  6. #include <transport/TSocket.h>  
  7. #include <transport/TTransportUtils.h>  
  8. using namespace std;  
  9. using namespace boost;  
  10. using namespace apache::thrift;  
  11. using namespace apache::thrift::protocol;  
  12. using namespace apache::thrift::transport;  
  13. using namespace scribe::thrift;  
  14. int main(int argc, char** argv)  
  15. {  
  16.   std::string category; // the log category  
  17.   std::string host;    // the ip host  
  18.   int port; // the port  
  19.     
  20.   if(argc == 2)  
  21.   {  
  22.     category.assign(argv[1]);  
  23.     host = "localhost";  
  24.     port = 1463;  
  25.   }else if (argc == 4 && strcmp(argv[1],"-h") == 0)  
  26.   {  
  27.     category.assign(argv[3]);  
  28.     char* sep = strstr(argv[2],":");  
  29.     if(sep == NULL)  
  30.     {  
  31.       host.assign(argv[2]);  
  32.       port = 1463;  
  33.     }  
  34.     else  
  35.     {  
  36.       char tmp[20];  
  37.       strncpy(tmp,argv[2],sep - argv[2]);  
  38.       port = atoi(sep+1);  
  39.       host.assign(tmp);  
  40.     }  
  41.   }else  
  42.   {  
  43.     printf("usage (message is stdin): scribe_cat [-h host[:port]] category");  
  44.     exit(1);  
  45.   }  
  46.     
  47.   shared_ptr<TTransport> socket(new TSocket(host, port));  
  48.   shared_ptr<TTransport> transport(new TFramedTransport(socket));  
  49.   shared_ptr<TProtocol> protocol(new TBinaryProtocol(transport));  
  50.   // use boost shared pointer  
  51.   shared_ptr<scribeClient> sbclient(new scribeClient(protocol));  
  52.   try  
  53.   {  
  54.     transport->open();  
  55.     // create a log entry and push it to vector  
  56.     LogEntry le;  
  57.     le.message = "This is a test message";  
  58.     le.category = category;  
  59.       
  60.     std::vector<LogEntry> messages;  
  61.     messages.push_back(le);  
  62.     // write to scribe server  
  63.     sbclient->Log(messages);  
  64.     // close the transport  
  65.     transport->close();  
  66.   }catch(TException &tx)  
  67.   {  
  68.     printf("ERROR: %s/n",tx.what());  
  69.   }  
  70.  }  

 

 

 

 相关的Makefile文件内容:

 

[c-sharp] view plaincopy
  1. CC=g++  
  2. LIBS=-lthrift -lfb303  
  3. INCLUDE=-I/usr/local/include/thrift/fb303 -I/usr/local/include/thrift  
  4. SOURCE=scribe_cat.cpp scribe.cpp scribe_types.cpp  
  5. scribe_cat: $(SOURCE)   
  6. $(CC) $(SOURCE) -o $@ $(INCLUDE) $(LIBS)  
  7. clean:  
  8. rm scribe_cat  

 

 

 

 

4. 参考

 

https://github.com/facebook/scribe

http://blog.nosqlfan.com/html/1287.html

http://incubator.apache.org/thrift/

 

 

转自:http://blog.csdn.net/amuseme_lu/article/details/6328013

posted @ 2012-04-24 17:40  vivianC  阅读(634)  评论(0)    收藏  举报