實時計算神器:binlog

囉哩八嗦html

可是對於有入庫還有本身記錄到日誌的這顯然是畫蛇添足。由於MySQL自己就有幫你記錄日誌, 並且記錄的日誌比本身應用程序的要準確的多(MySQL 須要開啓row模式)。python

  1. 解析MySQL Binlog,並獲取咱們想要的Event。
  2. 過濾出咱們關心的表。
  3. 將得到的相關數據實時的保存到相關存儲中(通常使用redis存數據,以後再定時刷入MySQL)。

模擬步驟:mysql

咱們這邊模擬實時算訂銷售總額,和訂單量。linux

  1. 使用python-mysql-replication做爲實時解析MySQL Binlog的日誌利器(推薦使用 阿里的 canal,這裏主要看公司的開發人員擅長什麼而決定)。
  2. 咱們只關心 WriteRowsEvent (事件號 30)。
  3. 咱們只關心 ord_order 表產生的 WriteRowsEvent 事件。
  4. 在原來統計的基礎上加上本次訂單的信息並保存到Redis(使用打印來代替保存到Redis)。

老套的 SQL 代碼redis

--建立演示的 ord_order 表
CREATE TABLE ord_order(
    order_id INT NOT NULL AUTO_INCREMENT COMMENT '訂單ID',
    amount INT NOT NULL DEFAULT 0 COMMENT '訂單金額(分)',
    create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '建立時間',
    PRIMARY KEY(order_id)
)COMMENT = '訂單表';
 
-- 查看 當前日誌所在位置
SHOW MASTER STATUS;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000012 |      469 |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+
 
-- 插入幾筆訂單
INSERT INTO ord_order(amount) VALUES
(1000),
(2000),
(3000);
 
-- 查看 當前日誌所在位置
SHOW MASTER STATUS;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000012 |      712 |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+

青澀的 Python 代碼sql

#!/usr/bin/env python
# -*- coding:utf-8 -*-
 
from pymysqlreplication import BinLogStreamReader
 
# 連接數據庫的參數 由於 pymysqlreplication 底層使用的是 python-mysql
mysql_settings = {
    'host': '192.168.1.233',
    'port': 3306,
    'user': 'HH',
    'passwd': 'oracle'
}
 
# 這 pymysqlreplication 的 server_id 和從 Binlog 的什麼位置開始解析
stream = BinLogStreamReader(connection_settings=mysql_settings,
                            server_id=100,
                            blocking=True,
                            log_file='mysql-bin.000012',
                            log_pos=469)
 
# 初始化訂單統計數據
order_count_total = 0
order_amount_total = 0
 
# 不停的解析 獲取解析的 Binlog
for binlogevent in stream:
 
    # 碰到 WriteRowsEvent 而且 表是 ord_order 則進行統計
    if binlogevent.event_type == 30 and binlogevent.table == 'ord_order':
        binlogevent.dump() # 打印事件相關信息
 
        # 同時計算出 訂單數 和 金額數組, 如: [(1, 9), (1, 4)]
        stat = [(1, row['values']['amount']) for row in binlogevent.rows]
 
        # 分別得到 訂單數數組如:[1, 1]。 銷售額, 如: [9, 4]
        order_count, order_amount = zip(*stat)
        order_count_total += sum(order_count)
        order_amount_total += sum(order_amount)
 
        # 打印本次事件 產生的訂單數和銷售額
        print 'order_count:', order_count
        print 'order_amount:', order_amount
 
        # 打印總的訂單數和銷售額
        print 'order_count_total:', order_count_total
        print 'order_amount_total:', order_amount_total

運行代碼數據庫

[root@centos7 tmp]# python test.py
=== WriteRowsEvent ===
Date: 2016-11-16T17:11:11
Log position: 681
Event size: 54
Read bytes: 12
Table: test.ord_order
Affected columns: 3
Changed rows: 3
Values:
--
('*', u'order_id', ':', 1)
('*', u'amount', ':', 1000)
('*', u'create_time', ':', datetime.datetime(2016, 11, 16, 17, 11, 11))
--
('*', u'order_id', ':', 2)
('*', u'amount', ':', 2000)
('*', u'create_time', ':', datetime.datetime(2016, 11, 16, 17, 11, 11))
--
('*', u'order_id', ':', 3)
('*', u'amount', ':', 3000)
('*', u'create_time', ':', datetime.datetime(2016, 11, 16, 17, 11, 11))
()
order_count: (1, 1, 1)
order_amount: (1000, 2000, 3000)
order_count_total: 3
order_amount_total: 6000

關鍵的不說, 氣死你 (^_^)centos

ALTER TABLE ord_order
    ADD PARTITION (PARTITION p201701 VALUES IN (201701));
     
ALTER TABLE ord_order DROP PARTITION p201601;
  1. MySQL 掛掉要如何處理。
  2. 如何實現程序的高可用。
  3. 如何記錄解析的 log file 和 log pos。
  4. 需不須要將解析的數據統一管理和存儲。

你們能夠考慮一下要如何實現上面的事情。具體如何作我就不說了。數組

原文來自:http://www.ttlsa.com/database/mysql-binlog-complete-real-time-computing/oracle

本文地址: http://www.linuxprobe.com/binlog-real-time-computing.html

相關文章
相關標籤/搜索