日志存储设计
日志具有格式松散、难以结构化的特点,同时日志的输出位置随机,数据量较大。因此,对于日志的存储方式要进行单独设计。
1.采用异步化的独立事务记录日志
日志异步存储设计如图6-19所示,日志的记录可能穿插于不同的业务和程序流程之间。日志虽然可以帮助技术人员做很多事情,但是所有的日志记录都不应该影响到用户的正常使用。因此,日志记录必须是独立的事务。
图6-19 日志异步存储设计
推荐采用异步方式处理,提高程序的响应速度。如果是小型系统,则可以直接采用异步线程池或内存队列的方式实现。如果是大型系统,则应该借助消息中间件(Kafka、ActiveMQ等)完成。
2.日志的存储设计
程序日志由于输出的内容不确定,因此具有非结构化的特点,通常采用分层滚动的文件存储方式。而登录日志、退出日志、操作日志和接口日志具有明确的数据结构,可以很方便地按照不同维度进行统计分析。
如果只采用关系型数据库存储,则可以很方便地按照各种维度进行分组、排序、聚合运算。但是,对于接口日志这种请求报文、应答报文就难以存储,因为这种数据需要占用很大的存储空间,使用CLOB 等类型的大文本字段,会导致数据查询性能急剧降低。
因此,可以采用关系型数据库和文档型数据库联合使用的方式进行存储,如图6-20所示。使用关系型数据库存储主交易内容,使用
MongoDB存储请求和应答报文等大文本内容,或者使用磁盘文件存储请求和应答日志。然后将关系型数据库与文档型数据库、文件按照交易流水号进行关联即可。
图6-20 日志数据库存储设计
关系型数据库和文档型数据库组合存储设计如图6-21所示,可以使用MySQL、Oracle等关系型数据库记录主要的结构化数据,如日志流水ID、客户端和服务端编码、请求和应答时间、交易耗时、接口编码信息。使用MongoDB等文档型数据库存储请求和应答的完整报文,
MySQL和MongoDB之间通过日志流水号主键进行关联。利用关系型数据库做各种维度的分组汇总,使用文档型数据库查询具体的交互报文。
图6-21 关系型数据库和文档型数据库组合存储设计
关系型数据库和磁盘文件组合存储设计如图6-22所示,可以使用磁盘文件存储请求和应答的完整日志,文件的名称使用日志流水号加后缀的形式,这样可以很方便地找到具体的交互日志。这种存储设计解决了MongoDB的存储空间占用过大的问题,磁盘文件也便于做定期备份的清理。
图6-22 关系型数据库和磁盘文件组合存储设计