分布式系统日志集中到一台服务器,将分布式中多台节点的日志信息集中到一个节点上...

本文详细介绍了如何在服务器(master)和客户端(slave)上配置rsyslog,包括使用TCP和UDP传输日志,自定义过滤特定主机和日志级别,并展示了Apache日志管理的实例。通过实例教程,读者可以学习如何设置日志接收、发送和高级过滤技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

转载:http://my.oschina.net/duxuefeng/blog/317570

1,准备

master:10.1.5.241

slave01:10.1.5.242

在服务器端和客户端分别安装rsyslog

[root@master ~]# yum -y rsyslog

[root@master ~]# rsyslogd -version

rsyslogd 5.8.10, compiled with:

FEATURE_REGEXP:                Yes

FEATURE_LARGEFILE:            No

GSSAPI Kerberos 5 support:        Yes

FEATURE_DEBUG (debug build, slow code):    No

32bit Atomic operations supported:    Yes

64bit Atomic operations supported:    Yes

Runtime Instrumentation (slow code):    No

See http://www.rsyslog.com for more information.

2,配置

配置文件如下:

[root@master ~]# egrep -v ‘^#|^$‘ /etc/rsyslog.conf

$ModLoad imuxsock # provides support for local system logging (e.g. via logger command)

$ModLoad imklog   # provides kernel logging support (previously done by rklogd)

$ModLoad immark  # provides --MARK-- message capability

$ModLoad imudp                            打开ucp连接,通过ucp传日志

$UDPServerRun 514

$ModLoad imtcp                                        打开tcp连接,通过tcp传日志

$InputTCPServerRun 10514

$ActionFileDefaultTemplate RSYSLOG_TraditionalFileFormat

$IncludeConfig /etc/rsyslog.d/*.conf

*.info;mail.none;authpriv.none;cron.none                /var/log/messages

authpriv.*                                              /var/log/secure

mail.*                                                  -/var/log/maillog

cron.*                                                  /var/log/cron

*.emerg                                                 *

uucp,news.crit                                          /var/log/spooler

local7.*                                                /var/log/boot.log

例子1,

简单配置:将所有系统log都放入服务器端下的/var/log/all.log下。

配置:

服务器:

/etc/rsyslog.conf文件最后添加

*.*                                    /var/log/all.log

[root@master ~]# /etc/init.d/rsyslog restart

客户端:

/etc/rsyslog.conf文件最后添加

*.*                                    @@10.1.5.241:10514    通过tcp传

[[email protected] ~]# /etc/init.d/rsyslog restart

测试:

tail -f /var/log/all.log

例子2,

自定义测试,

配置:

服务器:

/etc/rsyslog.conf文件最后添加

:fromhost,isequal, “slave01″ /var/log/all.log            #过滤来自lave01的日志,放入/var/log/all.log

:fromhost,isequal, “slave01″ ~

[[email protected] ~]# /etc/init.d/rsyslog restart

客户端:

*.*                    @10.1.5.241:514                     #通过udp传

[[email protected] ~]# /etc/init.d/rsyslog restart

测试:

[[email protected] ~]# logger "hello world"

[[email protected] ~]# tail -f /var/log/all.log

例子3,

自定义测试,

配置:

服务器:

/etc/rsyslog.conf文件最后添加

local5.*        /var/log/all.log            #过滤local5级别的日志,放入/var/log/all.log

local5.*        ~

[[email protected] ~]# /etc/init.d/rsyslog restart

客户端:

local5.*                    @10.1.5.241:514                     #通过udp传

[[email protected] ~]# /etc/init.d/rsyslog restart

测试:

[[email protected] ~]# logger -p local5.info  "hello world"          # 这里必须指定local5级别

[[email protected] ~]# tail -f /var/log/all.log

例子4,

自定义测试,

配置:

服务器:

/etc/rsyslog.conf文件最后添加

$template logfile,    "/var/log/logfile_%$year%%$month%%$day%.log"

:msg,contains,        "muyushan"            ?logfile

[[email protected] ~]# /etc/init.d/rsyslog restart

客户端:

:msg,contains,        "muyushan"                @@10.1.5.241:10514                     #通过tdp传

[[email protected] ~]# /etc/init.d/rsyslog restart

测试:

[[email protected] ~]# logger -t muyushan  "hello world"          # 在日志正文每行记录加上“muyushan”标签

[[email protected] ~]# tail -f /var/log/all.log

例子5,

apache日志管理

配置:

服务器:

mkdir /data/apache/logs

chown apache:apache /data/apache/logs

/etc/rsyslog.conf文件最后添加

$template access_log, "%msg:2:$%\n"

$template error_log, "%msg%\n"

# web1-access-log

$template access_log_file_web1, "/data/apache/logs/%$NOW%/access-log/web1-access_log"

# web1-error-log

$template error_log_file_web1, "/data/apache/logs/%$NOW%/error-log/web1-error_log"

# web1-access-log

if $syslogfacility-text == ‘local6‘ and $syslogtag == ‘http-access:‘ and $fromhost-ip == ‘10.1.5.241‘ then -?access_log_file_web1;access_log

# web1-error-log

if $syslogfacility-text == ‘local6‘ and $syslogtag == ‘http-error:‘ and $fromhost-ip == ‘10.1.5.241‘ then -?error_log_file_web1;error_log

[[email protected] ~]# /etc/init.d/rsyslog restart

客户端:

vim /etc/http/conf/httpd.conf

找到以下选项并将此选项标注#

CustomLog logs/access_log combined

ErrorLog logs/error_log

分别在此2个选项下添加如下内容

CustomLog "|/usr/bin/logger -p local6.info -t http-access" combined

ErrorLog "| /usr/bin/logger -p local6.info -t http-error"

/etc/rsyslog.conf文件最后添加

local5.*        /var/log/all.log            #过滤local5级别的日志,放入/var/log/all.log

local5.*        ~

[[email protected] ~]# /etc/init.d/rsyslog restart

测试:

[[email protected] ~]# tail -f /data/apache/logs/%$NOW%/access-log/web1-access_log

[[email protected] ~]# tail -f /data/apache/logs/%$NOW%/error-log/web1-error_log

附录:

日志设备(可以理解为日志类型)

日志设备/类型

说明

auth

–pam产生的日志

authpriv

–ssh,ftp等登录信息的验证信息

cron

–时间任务相关

kern

–内核

lpr

–打印

mail

–邮件

mark(syslog)

–rsyslog服务内部的信息,时间标识

news

–新闻组

user

–用户程序产生的相关信息

uucp

–unix to unix copy, unix主机之间相关的通讯

local 1~7

–自定义的日志设备

日志级别

从上到下,级别从低到高,记录的信息越来越少 详细的可以查看手册: man 3 syslog

级别

说明

级别值

debug

–有调式信息的,日志信息最多

7

info

–一般信息的日志,最常用

notice

–最具有重要性的普通条件的信息

warning

–警告级别

4

err

–错误级别,阻止某个功能或者模块不能正常工作的信息

crit

–严重级别,阻止整个系统或者整个软件不能正常工作的信息

alert

–需要立刻修改的信息

emerg

–内核崩溃等严重信息

none

–什么都不记录

连接符号

连接符号

说明

.xxx

表示大于等于xxx级别的信息

.=xxx

表示等于xxx级别的信息

.!xxx

表示在xxx之外的等级的信息

示例:

:msg,contains,"error"        # 选择包含 error 的日志

:hostname,isequal, "host1"   # 选择主机名为 host1 的日志

:msg,!regex,"fatal .* error" # 选择不匹配指定正则表达式的日志

logger的使用

logger 是一个shell 命令接口,可以通过该接口使用Syslog的系统日志模块,还可以从命令行直接向系统日志文件写入一行信息。

logger -it error  -p local5.info "hello world"

-i 在每行都记录进程ID

-t 日志中的每一行都加一个error标签

-p 指定自定义的日志设备,和配置文件的local5.*对应,配置文件里没有.info。

说明,如果是自己写的程序,在生成日志的代码中需要用logger命令转到系统的日志接口。

原文:http://www.cnblogs.com/wzyxidian/p/4895204.html

<think>我们正在构建一个分布式爬虫,并将数据保存到远程MySQL服务器。同时,我们也希望支持MongoDB、Redis和Elasticsearch作为存储选项。考虑到分布式爬虫的特点,我们需要设计一个灵活的存储后端,可以配置不同的存储方式。步骤:1.分布式爬虫框架选择:Scrapy-Redis是一个常用的分布式爬虫框架,它基于Redis实现分布式调度。2.数据存储设计:我们需要编写一个可扩展的数据存储管道(pipeline),以便支持多种存储引擎。我们将按照以下步骤进行:一、搭建分布式爬虫环境(使用Scrapy-Redis)二、配置远程MySQL、MongoDB、Redis、Elasticsearch的连接信息三、编写存储管道(pipeline)以支持多种存储方式详细步骤:一、搭建分布式爬虫环境1.安装必要的库:scrapy,scrapy-redis,redis2.创建Scrapy项目,配置使用Scrapy-Redis调度器。二、配置存储服务的连接信息我们可以在Scrapy项目的settings.py中配置不同存储的连接字符串,例如:MYSQL_HOST='remote_host'MYSQL_PORT=3306MYSQL_USER='user'MYSQL_PASSWORD='password'MYSQL_DB='database_name'同样,配置MongoDB、Redis、Elasticsearch的连接信息。三、编写存储管道我们将为每种存储方式编写一个管道类,然后在settings.py中激活需要使用的管道。示例管道:1.MySQL管道:将数据存储到MySQL2.MongoDB管道:将数据存储到MongoDB3.Redis管道:将数据存储到Redis(例如作为缓存或消息队列)4.Elasticsearch管道:将数据存储到Elasticsearch(用于搜索)我们可以同时使用多个管道,这样爬取的数据可以同时存入多个存储系统。代码示例:1.MySQL管道(pipelines.py):需要安装pymysql或mysql-connector-python2.MongoDB管道(pipelines.py):需要安装pymongo3.Elasticsearch管道(pipelines.py):需要安装elasticsearch4.Redis管道(pipelines.py):注意:Redis通常用作缓存或消息队列,因此存储方式可能是以键值对的形式存储数据,或者作为其他用途。这里可以根据需求设计。下面分别给出这些管道的示例代码:注意:在settings.py中配置管道优先级,例如:ITEM_PIPELINES={'myproject.pipelines.MySQLPipeline':300,'myproject.pipelines.MongoDBPipeline':400,'myproject.pipelines.ElasticsearchPipeline':500,'myproject.pipelines.RedisPipeline':600,}每个管道类中,我们都需要在open_spider方法中建立连接,在close_spider方法中关闭连接,在process_item方法中处理数据。考虑到分布式爬虫可能同时运行多个爬虫节点,存储系统应该能够处理并发写入。具体代码实现:1.MySQL管道示例:在settings.py中配置MySQL连接信息:MYSQL_HOST='your_remote_mysql_host'MYSQL_PORT=3306#默认端口MYSQL_USER='username'MYSQL_PASSWORD='password'MYSQL_DB='database_name'MYSQL_TABLE='table_name'在pipelines.py中:importpymysqlfrom.settingsimportMYSQL_HOST,MYSQL_PORT,MYSQL_USER,MYSQL_PASSWORD,MYSQL_DB,MYSQL_TABLEclassMySQLPipeline:defopen_spider(self,spider):self.connection=pymysql.connect(host=MYSQL_HOST,port=MYSQL_PORT,user=MYSQL_USER,password=MYSQL_PASSWORD,db=MYSQL_DB,charset='utf8mb4',cursorclass=pymysql.cursors.DictCursor)self.cursor=self.connection.cursor()defclose_spider(self,spider):self.connection.close()defprocess_item(self,item,spider):#根据item构建SQL语句keys=','.join(item.keys())values=','.join(['%s']*len(item))sql=f'INSERTINTO{MYSQL_TABLE}({keys})VALUES({values})'self.cursor.execute(sql,tuple(item.values()))self.connection.commit()returnitem2.MongoDB管道示例:在settings.py中配置MongoDB连接信息:MONGODB_URI='mongodb://user:password@remote_host:27017/'MONGODB_DB='database_name'MONGODB_COLLECTION='collection_name'在pipelines.py中:importpymongofrom.settingsimportMONGODB_URI,MONGODB_DB,MONGODB_COLLECTIONclassMongoDBPipeline:defopen_spider(self,spider):self.client=pymongo.MongoClient(MONGODB_URI)self.db=self.client[MONGODB_DB]self.collection=self.db[MONGODB_COLLECTION]defclose_spider(self,spider):self.client.close()defprocess_item(self,item,spider):self.collection.insert_one(dict(item))returnitem3.Elasticsearch管道示例:在settings.py中配置Elasticsearch连接信息:ES_HOSTS=['http://remote_host:9200']#可以是多个节点ES_INDEX='index_name'ES_USER='username'#如果需要认证ES_PASSWORD='password'在pipelines.py中:fromelasticsearchimportElasticsearchfrom.settingsimportES_HOSTS,ES_USER,ES_PASSWORD,ES_INDEXclassElasticsearchPipeline:defopen_spider(self,spider):self.es=Elasticsearch(ES_HOSTS,http_auth=(ES_USER,ES_PASSWORD)ifES_USERandES_PASSWORDelseNone)defprocess_item(self,item,spider):#将item转换为文档doc=dict(item)#使用id或者由Elasticsearch自动生成_idself.es.index(index=ES_INDEX,document=doc)returnitem#注意:由于Elasticsearch客户端是长连接,可以不需要在close_spider中做特别处理,但为了规范我们可以关闭连接?#实际上,Elasticsearch客户端不需要显式关闭,但我们可以关闭来释放资源。defclose_spider(self,spider):self.es.close()4.Redis管道示例:在settings.py中配置Redis连接信息:REDIS_HOST='remote_host'REDIS_PORT=6379REDIS_PASSWORD=None#如果有密码则配置REDIS_DB=0#选择数据库在pipelines.py中:importredisimportjsonfrom.settingsimportREDIS_HOST,REDIS_PORT,REDIS_PASSWORD,REDIS_DBclassRedisPipeline:defopen_spider(self,spider):self.client=redis.Redis(host=REDIS_HOST,port=REDIS_PORT,password=REDIS_PASSWORD,db=REDIS_DB)defprocess_item(self,item,spider):#Redis通常以键值对存储。这里我们使用一个列表或者集合来存储item,或者使用哈希表?#具体方式取决于需求:如果作为缓存,我们可以设置一个过期时间;如果作为数据存储,我们可以考虑永久存储。#这里我们使用字符串类型存储,将item转为json字符串,然后以一个键名存储(注意键名的设计,例如使用spider.name和item的id)#假设item有一个'id'字段key=f"{spider.name}:{item['id']}"#或者如果不需要单独存储每个item,而是用列表存储,可以使用lpush#这里以字符串形式存储每个itemself.client.set(key,json.dumps(dict(item)))#或者使用哈希表:hmset(注意:hmset在redis-py中可以使用hset替代,因为hmset已被弃用)#以哈希表存储的例子(如果item字段较多,且需要单独访问某些字段,可以用哈希):#self.client.hset(key,mapping=dict(item))#我们这里简单用字符串存储returnitemdefclose_spider(self,spider):self.client.close()#redis连接不需要显式关闭?redis-py的连接是使用连接池的,但显式关闭连接是好的做法注意:以上代码示例均为基本实现,实际使用中需要根据数据结构和需求调整。同时,为了提高性能,可以考虑批量写入(如MySQL的批量插入、MongoDB的批量插入、Elasticsearch的批量API)。四、分布式爬虫节点配置使用Scrapy-Redis时,配置settings.py:#使用scrapy_redis的调度器SCHEDULER="scrapy_redis.scheduler.Scheduler"#使用scrapy_redis的去重组件DUPEFILTER_CLASS="scrapy_redis.dupefilter.RFPDupeFilter"#允许爬取后暂停,然后继续(不清空队列)SCHEDULER_PERSIST=True#指定连接Redis的信息REDIS_HOST='remote_redis_host'REDIS_PORT=6379#如果Redis有密码#REDIS_PASSWORD='password'在爬虫中,从Redis队列获取起始URL,例如:fromscrapy_redis.spidersimportRedisSpiderclassMyDistributedSpider(RedisSpider):name='distributed_spider'redis_key='my_spider:start_urls'#Redis中的键,用于获取起始URL这样,多个爬虫节点会从同一个Redis队列中获取任务。五、部署到多个节点将爬虫代码部署到多台服务器上,并启动爬虫。确保所有爬虫节点可以访问Redis服务(用于任务调度)以及各个存储服务(MySQL,MongoDB,etc.)。六、启动爬虫在Redis中推送起始URL(lpush):lpushmy_spider:start_urlshttp://example.com/page1然后在各个节点运行爬虫:scrapyrunspidermyspider.py这样,我们就搭建了一个分布式爬虫,并将数据存储到多种存储系统中。额外加分:支持MongoDB、Redis或Elasticsearch存储,我们已经在管道中实现了。注意:以上代码仅为示例,实际应用中需要考虑错误处理、数据去重、增量爬取等问题。参考文献:[1]Scrapy-Redis文档:https://github.com/rmax/scrapy-redis[2]PyMySQL文档:https://pypi.org/project/PyMySQL/[3]PyMongo文档:https://pymongo.readthedocs.io/en/stable/[4]ElasticsearchPython客户端文档:https://elasticsearch-py.readthedocs.io/[5]Redis-py文档:https://redis-py.readthedocs.io/</think> ### 分布式爬虫数据存储方案(支持 MySQL/MongoDB/Redis/Elasticsearch) 以下是一个完整的分布式爬虫架构实现方案,重点解决数据存储到远程 MySQL 节点,并支持 MongoDB、Redis 和 Elasticsearch 多存储方案: #### 一、系统架构设计 ``` ┌─────────────────┐ ┌──────────────────┐ ┌──────────────┐ │ 分布式爬虫节点 │───▶ │ 消息队列 │───▶ │ 数据存储层 │ │ (Scrapy-Redis) │ │ (Redis/RabbitMQ) │ │ (多存储支持) │ └─────────────────┘ └──────────────────┘ └──────────────┘ ▲ │ │ ▼ └───────────────┐ ┌───────────────┐ │ │ 数据消费服务 │ └──────┤ (Python Worker)│ └───────────────┘ ``` #### 二、核心实现步骤 **1. 分布式爬虫框架搭建 (使用 Scrapy-Redis)** ```python # settings.py SCHEDULER = "scrapy_redis.scheduler.Scheduler" DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter" REDIS_URL = 'redis://:<password>@<redis-host>:6379/0' # Redis连接地址 # pipelines.py (数据推送到消息队列) class RedisPipeline: def process_item(self, item, spider): redis_conn.lpush('crawler:items', json.dumps(dict(item))) return item ``` **2. 数据存储服务实现 (核心存储逻辑)** ```python class StorageService: def __init__(self): # 初始化所有数据库连接 self.mysql_conn = pymysql.connect( host='mysql-host', user='user', password='pass', database='db' ) self.mongo_client = pymongo.MongoClient( 'mongodb://user:pass@mongo-host:27017/' ) self.es = Elasticsearch(['http://es-host:9200']) self.redis = redis.Redis(host='redis-host', port=6379) def save_to_mysql(self, item): with self.mysql_conn.cursor() as cursor: sql = """INSERT INTO scraped_data (url, title, content) VALUES (%s, %s, %s)""" cursor.execute(sql, (item['url'], item['title'], item['content'])) self.mysql_conn.commit() def save_to_mongodb(self, item): self.mongo_client.crawler.data.insert_one({ 'url': item['url'], 'title': item['title'], 'timestamp': datetime.now() }) def save_to_elasticsearch(self, item): self.es.index( index='web-content', document={ 'url': item['url'], 'content': item['content'] } ) def save_to_redis(self, item): self.redis.hset(f'page:{item["id"]}', mapping=item) def process_item(self, item_data): item = json.loads(item_data) # 根据配置选择存储引擎 if STORAGE_ENGINE == 'mysql': self.save_to_mysql(item) elif STORAGE_ENGINE == 'mongodb': self.save_to_mongodb(item) ... ``` **3. 多存储引擎配置** ```python # config.py STORAGE_ENGINE = 'mysql' # 可选:mysql/mongodb/elasticsearch/redis/all # 同时支持多引擎写入 if STORAGE_ENGINE == 'all': self.save_to_mysql(item) self.save_to_mongodb(item) self.save_to_elasticsearch(item) self.save_to_redis(item) ``` **4. 部署方案** 1. **数据库准备** (所有存储引擎需要预先配置): ```bash # MySQL CREATE DATABASE crawler; CREATE TABLE scraped_data(id INT AUTO_INCREMENT PRIMARY KEY, ...); # MongoDB use crawler db.createCollection("data") # Elasticsearch PUT /web-content { "mappings": { ... } } ``` 2. **Docker 部署数据库** [^3]: ```bash # 启动MySQL容器 docker run --name mysql -e MYSQL_ROOT_PASSWORD=pass -p 3306:3306 -d mysql:8 # 启动MongoDB容器 docker run --name mongo -p 27017:27017 -d mongo # 启动Elasticsearch容器 docker run --name es -p 9200:9200 -p 9300:9300 -d docker.elastic.co/elasticsearch/elasticsearch:8.5.1 ``` 3. 分布式部署爬虫节点: ```bash # 在所有爬虫节点 scrapy runspider myspider.py ``` #### 三、性能优化建议 1. **批量写入**:MySQL/MongoDB/ES 支持批量写入 2. **连接池**:为每个存储引擎配置连接池 3. **数据分片**:对MySQL分表、MongoDB分片、ES分片[^2] 4. **Redis缓存队列**:使用LPUSH/BRPOP模式提升吞吐量 #### 四、存储引擎选择建议 | 存储引擎 | 最佳场景 | 性能基准[^1] | |--------------|-----------------------------|----------------------| | **MySQL** | 关系型数据/事务性需求 | 10k-20k TPS | | **MongoDB** | 非结构化数据/灵活schema | 30k-50k 写入/秒 | | **Elasticsearch** | 全文搜索/日志分析 | 10k-15k 文档/秒 | | **Redis** | 实时缓存/去重队列 | 100k+ 操作/秒 |
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值