{"id":45549,"date":"2023-04-11T21:24:43","date_gmt":"2023-04-11T13:24:43","guid":{"rendered":"http:\/\/gulass.cn\/?p=45549"},"modified":"2023-04-11T21:24:43","modified_gmt":"2023-04-11T13:24:43","slug":"binlog-real-time-computing","status":"publish","type":"post","link":"https:\/\/gulass.cn\/binlog-real-time-computing.html","title":{"rendered":"\u5b9e\u65f6\u8ba1\u7b97\u795e\u5668\uff1abinlog"},"content":{"rendered":"\n\n\n
\u5bfc\u8bfb<\/td>\n\u7531\u4e8e\u4e1a\u52a1\u7684\u53d1\u5c55\uff0c\u4e00\u4e9b\u5b9e\u65f6\u7edf\u8ba1\u7684\u9700\u6c42\u8d8a\u6765\u8d8a\u591a\u3002\u600e\u4e48\u529e\u5462\uff1f<\/strong><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n
\u5570\u54e9\u516b\u55e6<\/strong><\/div>\n

\u4f46\u662f\u5bf9\u4e8e\u6709\u5165\u5e93\u8fd8\u6709\u81ea\u5df1\u8bb0\u5f55\u5230\u65e5\u5fd7\u7684\u8fd9\u663e\u7136\u662f\u591a\u6b64\u4e00\u4e3e\u3002\u56e0\u4e3aMySQL\u672c\u8eab\u5c31\u6709\u5e2e\u4f60\u8bb0\u5f55\u65e5\u5fd7, \u800c\u4e14\u8bb0\u5f55\u7684\u65e5\u5fd7\u6bd4\u81ea\u5df1\u5e94\u7528\u7a0b\u5e8f\u7684\u8981\u51c6\u786e\u7684\u591a(MySQL \u9700\u8981\u5f00\u542frow\u6a21\u5f0f)\u3002<\/p>\n

    \n
  1. \u89e3\u6790MySQL Binlog\uff0c\u5e76\u83b7\u53d6\u6211\u4eec\u60f3\u8981\u7684Event\u3002<\/li>\n
  2. \u8fc7\u6ee4\u51fa\u6211\u4eec\u5173\u5fc3\u7684\u8868\u3002<\/li>\n
  3. \u5c06\u83b7\u5f97\u7684\u76f8\u5173\u6570\u636e\u5b9e\u65f6\u7684\u4fdd\u5b58\u5230\u76f8\u5173\u5b58\u50a8\u4e2d(\u4e00\u822c\u4f7f\u7528redis\u5b58\u6570\u636e\uff0c\u4e4b\u540e\u518d\u5b9a\u65f6\u5237\u5165MySQL)\u3002<\/li>\n<\/ol>\n

    \u6a21\u62df\u6b65\u9aa4\uff1a<\/p>\n

    \u6211\u4eec\u8fd9\u8fb9\u6a21\u62df\u5b9e\u65f6\u7b97\u8ba2\u9500\u552e\u603b\u989d\uff0c\u548c\u8ba2\u5355\u91cf\u3002<\/p>\n

      \n
    1. \u4f7f\u7528python-mysql-replication\u4f5c\u4e3a\u5b9e\u65f6\u89e3\u6790MySQL Binlog\u7684\u65e5\u5fd7\u5229\u5668(\u63a8\u8350\u4f7f\u7528 \u963f\u91cc\u7684 canal\uff0c\u8fd9\u91cc\u4e3b\u8981\u770b\u516c\u53f8\u7684\u5f00\u53d1\u4eba\u5458\u64c5\u957f\u4ec0\u4e48\u800c\u51b3\u5b9a)\u3002<\/li>\n
    2. \u6211\u4eec\u53ea\u5173\u5fc3 WriteRowsEvent (\u4e8b\u4ef6\u53f7 30)\u3002<\/li>\n
    3. \u6211\u4eec\u53ea\u5173\u5fc3 ord_order \u8868\u4ea7\u751f\u7684 WriteRowsEvent \u4e8b\u4ef6\u3002<\/li>\n
    4. \u5728\u539f\u6765\u7edf\u8ba1\u7684\u57fa\u7840\u4e0a\u52a0\u4e0a\u672c\u6b21\u8ba2\u5355\u7684\u4fe1\u606f\u5e76\u4fdd\u5b58\u5230Redis(\u4f7f\u7528\u6253\u5370\u6765\u4ee3\u66ff\u4fdd\u5b58\u5230Redis)\u3002<\/li>\n<\/ol>\n
      \u8001\u5957\u7684 SQL \u4ee3\u7801<\/strong><\/div>\n
      --\u521b\u5efa\u6f14\u793a\u7684 ord_order \u8868\r\nCREATE TABLE ord_order(\r\n    order_id INT NOT NULL AUTO_INCREMENT COMMENT '\u8ba2\u5355ID',\r\n    amount INT NOT NULL DEFAULT 0 COMMENT '\u8ba2\u5355\u91d1\u989d(\u5206)',\r\n    create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '\u521b\u5efa\u65f6\u95f4',\r\n    PRIMARY KEY(order_id)\r\n)COMMENT = '\u8ba2\u5355\u8868';\r\n \r\n-- \u67e5\u770b \u5f53\u524d\u65e5\u5fd7\u6240\u5728\u4f4d\u7f6e\r\nSHOW MASTER STATUS;\r\n+------------------+----------+--------------+------------------+-------------------+\r\n| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |\r\n+------------------+----------+--------------+------------------+-------------------+\r\n| mysql-bin.000012 |      469 |              |                  |                   |\r\n+------------------+----------+--------------+------------------+-------------------+\r\n \r\n-- \u63d2\u5165\u51e0\u7b14\u8ba2\u5355\r\nINSERT INTO ord_order(amount) VALUES\r\n(1000),\r\n(2000),\r\n(3000);\r\n \r\n-- \u67e5\u770b \u5f53\u524d\u65e5\u5fd7\u6240\u5728\u4f4d\u7f6e\r\nSHOW MASTER STATUS;\r\n+------------------+----------+--------------+------------------+-------------------+\r\n| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |\r\n+------------------+----------+--------------+------------------+-------------------+\r\n| mysql-bin.000012 |      712 |              |                  |                   |\r\n+------------------+----------+--------------+------------------+-------------------+<\/pre>\n
      \u9752\u6da9\u7684 Python \u4ee3\u7801<\/strong><\/div>\n
      #!\/usr\/bin\/env python\r\n# -*- coding:utf-8 -*-\r\n \r\nfrom pymysqlreplication import BinLogStreamReader\r\n \r\n# \u94fe\u63a5\u6570\u636e\u5e93\u7684\u53c2\u6570 \u56e0\u4e3a pymysqlreplication \u5e95\u5c42\u4f7f\u7528\u7684\u662f python-mysql\r\nmysql_settings = {\r\n    'host': '192.168.1.233',\r\n    'port': 3306,\r\n    'user': 'HH',\r\n    'passwd': 'oracle'\r\n}\r\n \r\n# \u8fd9 pymysqlreplication \u7684 server_id \u548c\u4ece Binlog \u7684\u4ec0\u4e48\u4f4d\u7f6e\u5f00\u59cb\u89e3\u6790\r\nstream = BinLogStreamReader(connection_settings=mysql_settings,\r\n                            server_id=100,\r\n                            blocking=True,\r\n                            log_file='mysql-bin.000012',\r\n                            log_pos=469)\r\n \r\n# \u521d\u59cb\u5316\u8ba2\u5355\u7edf\u8ba1\u6570\u636e\r\norder_count_total = 0\r\norder_amount_total = 0\r\n \r\n# \u4e0d\u505c\u7684\u89e3\u6790 \u83b7\u53d6\u89e3\u6790\u7684 Binlog\r\nfor binlogevent in stream:\r\n \r\n    # \u78b0\u5230 WriteRowsEvent \u5e76\u4e14 \u8868\u662f ord_order \u5219\u8fdb\u884c\u7edf\u8ba1\r\n    if binlogevent.event_type == 30 and binlogevent.table == 'ord_order':\r\n        binlogevent.dump() # \u6253\u5370\u4e8b\u4ef6\u76f8\u5173\u4fe1\u606f\r\n \r\n        # \u540c\u65f6\u8ba1\u7b97\u51fa \u8ba2\u5355\u6570 \u548c \u91d1\u989d\u6570\u7ec4, \u5982: [(1, 9), (1, 4)]\r\n        stat = [(1, row['values']['amount']) for row in binlogevent.rows]\r\n \r\n        # \u5206\u522b\u83b7\u5f97 \u8ba2\u5355\u6570\u6570\u7ec4\u5982:[1, 1]\u3002 \u9500\u552e\u989d, \u5982: [9, 4]\r\n        order_count, order_amount = zip(*stat)\r\n        order_count_total += sum(order_count)\r\n        order_amount_total += sum(order_amount)\r\n \r\n        # \u6253\u5370\u672c\u6b21\u4e8b\u4ef6 \u4ea7\u751f\u7684\u8ba2\u5355\u6570\u548c\u9500\u552e\u989d\r\n        print 'order_count:', order_count\r\n        print 'order_amount:', order_amount\r\n \r\n        # \u6253\u5370\u603b\u7684\u8ba2\u5355\u6570\u548c\u9500\u552e\u989d\r\n        print 'order_count_total:', order_count_total\r\n        print 'order_amount_total:', order_amount_total<\/pre>\n

      \u8fd0\u884c\u4ee3\u7801<\/p>\n

      [root@centos7 tmp]# python test.py\r\n=== WriteRowsEvent ===\r\nDate: 2016-11-16T17:11:11\r\nLog position: 681\r\nEvent size: 54\r\nRead bytes: 12\r\nTable: test.ord_order\r\nAffected columns: 3\r\nChanged rows: 3\r\nValues:\r\n--\r\n('*', u'order_id', ':', 1)\r\n('*', u'amount', ':', 1000)\r\n('*', u'create_time', ':', datetime.datetime(2016, 11, 16, 17, 11, 11))\r\n--\r\n('*', u'order_id', ':', 2)\r\n('*', u'amount', ':', 2000)\r\n('*', u'create_time', ':', datetime.datetime(2016, 11, 16, 17, 11, 11))\r\n--\r\n('*', u'order_id', ':', 3)\r\n('*', u'amount', ':', 3000)\r\n('*', u'create_time', ':', datetime.datetime(2016, 11, 16, 17, 11, 11))\r\n()\r\norder_count: (1, 1, 1)\r\norder_amount: (1000, 2000, 3000)\r\norder_count_total: 3\r\norder_amount_total: 6000<\/pre>\n
      \u5173\u952e\u7684\u4e0d\u8bf4, \u6c14\u6b7b\u4f60 (^_^)<\/strong><\/div>\n
      ALTER TABLE ord_order\r\n    ADD PARTITION (PARTITION p201701 VALUES IN (201701));\r\n     \r\nALTER TABLE ord_order DROP PARTITION p201601;<\/pre>\n
        \n
      1. MySQL \u6302\u6389\u8981\u5982\u4f55\u5904\u7406\u3002<\/li>\n
      2. \u5982\u4f55\u5b9e\u73b0\u7a0b\u5e8f\u7684\u9ad8\u53ef\u7528\u3002<\/li>\n
      3. \u5982\u4f55\u8bb0\u5f55\u89e3\u6790\u7684 log file \u548c log pos\u3002<\/li>\n
      4. \u9700\u4e0d\u9700\u8981\u5c06\u89e3\u6790\u7684\u6570\u636e\u7edf\u4e00\u7ba1\u7406\u548c\u5b58\u50a8\u3002<\/li>\n<\/ol>\n

        \u5927\u5bb6\u53ef\u4ee5\u8003\u8651\u4e00\u4e0b\u8981\u5982\u4f55\u5b9e\u73b0\u4e0a\u9762\u7684\u4e8b\u60c5\u3002\u5177\u4f53\u5982\u4f55\u505a\u6211\u5c31\u4e0d\u8bf4\u4e86\u3002<\/p>\n

        \n

        \u539f\u6587\u6765\u81ea\uff1ahttp:\/\/www.ttlsa.com\/database\/mysql-binlog-complete-real-time-computing\/<\/a><\/p>\n

        \u672c\u6587\u5730\u5740\uff1a http:\/\/gulass.cn\/binlog-real-time-computing.html<\/a>\u7f16\u8f91\uff1a\u6768\u9e4f\u98de\uff0c\u5ba1\u6838\u5458\uff1a\u5cb3\u56fd\u5e05<\/span><\/p>\n<\/blockquote>\n","protected":false},"excerpt":{"rendered":"

        \u5bfc\u8bfb \u7531\u4e8e\u4e1a\u52a1\u7684\u53d1\u5c55\uff0c\u4e00\u4e9b\u5b9e\u65f6\u7edf\u8ba1\u7684\u9700\u6c42\u8d8a\u6765\u8d8a\u591a\u3002\u600e\u4e48\u529e\u5462\uff1f \u5570\u54e9\u516b\u55e6 \u4f46\u662f\u5bf9\u4e8e\u6709\u5165\u5e93\u8fd8\u6709\u81ea\u5df1\u8bb0\u5f55\u5230\u65e5\u5fd7\u7684\u8fd9\u663e […]<\/p>\n","protected":false},"author":63,"featured_media":33501,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[55],"tags":[],"class_list":["post-45549","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-thread"],"acf":[],"_links":{"self":[{"href":"https:\/\/gulass.cn\/wp-json\/wp\/v2\/posts\/45549","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/gulass.cn\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/gulass.cn\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/gulass.cn\/wp-json\/wp\/v2\/users\/63"}],"replies":[{"embeddable":true,"href":"https:\/\/gulass.cn\/wp-json\/wp\/v2\/comments?post=45549"}],"version-history":[{"count":7,"href":"https:\/\/gulass.cn\/wp-json\/wp\/v2\/posts\/45549\/revisions"}],"predecessor-version":[{"id":269368,"href":"https:\/\/gulass.cn\/wp-json\/wp\/v2\/posts\/45549\/revisions\/269368"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/gulass.cn\/wp-json\/wp\/v2\/media\/33501"}],"wp:attachment":[{"href":"https:\/\/gulass.cn\/wp-json\/wp\/v2\/media?parent=45549"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/gulass.cn\/wp-json\/wp\/v2\/categories?post=45549"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/gulass.cn\/wp-json\/wp\/v2\/tags?post=45549"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}