Mysql pool cluster với nodejs Ngay từ đầu mà triển khai là ngon rồi.

Nội dung bài viết

Video học lập trình mỗi ngày

Sau khi chúng tôi check về hiệu suất khi sử dụng kết nối với phương thức createPool() mà mysql đã cung cấp thì chúng tôi đã có được những điều mà mình mong đợi khi triển khai một hệ thống lớn về thương mai điện tử. 


Nhưng khi triển khai kết nối với database có thiết kế lên đến 1 triệu connects thì chỉ sử dụng createPool() là không đủ, chính vì vậy chúng tôi, lại triển khai một kết nối khác đó là sử dụng phương thức createPoolCluster() mà mysql đã làm rất tốt. Chính vì vậy có những lý do mà đến cả ông lớn như facebook đến nay vẫn sử dụng Mysql làm db chính của họ.


Mysql nodejs hướng dẫn kết nối với createPoolCluster


Sau khi chúng tôi đã có nhiều khách hàng sử dụng sàn thương mại của chúng tôi vì đã giải quyết được nhiều vấn đề làm hệ thống chậm, nếu bạn chưa biết có thể quay trở lại bài viết trước để tìm hiểu chúng. 


Chính vì lượng kết nối ngày càng tăng và chúng tôi đã có dự liệu trước tình huống đọc nhiều hơn ghi. Về việc triển khai master slave trong mysql đã được chúng tôi sử dụng, và cũng như thế chúng tôi đã phân tích việc máy chủ nào đọc và máy chủ nào ghi như thế nào? Để hình dung câu chuyện thì để tôi nói qua một chút về vấn đề này.


MySQL master slave


Cần phải hiểu vì sao Mysql triển khai mô hình này, lý do thì có nhiều nhưng chủ yếu là để tránh xung đột khoá, vì nếu xung đột thì deadlock là chuyện xảy ra như cơm bữa. Và chính vì vậy, cần phải chia ra master chính là để ghi, và slave đọc. Có thể một master nhưng nhiều slave. Khi master ghi thì tạo ra một binlog, và các slave dựa vào file binlog để đồng bộ dữ liệu. 


Cụ thể như sau, ở sàn thương mại của chúng tôi, thì một người đăng bán hàng, chỉ một lần tạo bài viết, thì gọi là một lần ghi, thế nhưng có hàng triệu người đọc sản phẩm ấy. Như vậy tỷ lệ ghi và đọc là chênh lệch khá lớn. Cũng từ đó chúng tôi có thể giảm cấu hình của server WRITE lại, và tăng cấu hình của server READ lên. Tuỳ theo các tình huống cụ thể. 


Tiếp theo nói về vấn đề làm thế nào triển khai một connection mysql nodejs luôn luôn có sẵn, chỉ việc query mà thôi. Thì sử dụng createPoolCluster(), sau đây là chúng taooi tạo ra một file gọi là db.js 


### db.js


var mysql = require('mysql')
  , async = require('async')

var PRODUCTION_DB = 'app_prod_database'
  , TEST_DB = 'app_test_database'

exports.MODE_TEST = 'mode_test'
exports.MODE_PRODUCTION = 'mode_production'

var state = {
  pool: null,
  mode: null,
}

exports.connect = function(mode, done) {
  if (mode === exports.MODE_PRODUCTION) {
    state.pool = mysql.createPoolCluster()

    state.pool.add('WRITE', {
      host: '192.168.0.5',
      user: 'your_user',
      password: 'some_secret',
      database: PRODUCTION_DB
    })

    state.pool.add('READ1', {
      host: '192.168.0.6',
      user: 'your_user',
      password: 'some_secret',
      database: PRODUCTION_DB
    })

    state.pool.add('READ2', {
      host: '192.168.0.7',
      user: 'your_user',
      password: 'some_secret',
      database: PRODUCTION_DB
    })
  } else {
    state.pool = mysql.createPool({
      host: 'localhost',
      user: 'your_user',
      password: 'some_secret',
      database: TEST_DB
    })
  }

  state.mode = mode
  done()
}

exports.READ = 'read'
exports.WRITE = 'write'

exports.get = function(type, done) {
  var pool = state.pool
  if (!pool) return done(new Error('Missing database connection.'))

  if (type === exports.WRITE) {
    state.pool.getConnection('WRITE', function (err, connection) {
      if (err) return done(err)
      done(null, connection)
    })
  } else {
    state.pool.getConnection('READ*', function (err, connection) {
      if (err) return done(err)
      done(null, connection)
    })
  }
}

Chú ý ở đây là chúng tôi triển khai 3 máy chủ, một dành cho WRITE , và 2 dành cho READ. Và phương thức get() là lấy connect để query. Vậy chúng sử dụng như thế nào?

var db = require('../db.js')

exports.create = function(userId, text, done) {
  var values = [userId, text, new Date().toISOString()]
  
  db.get(db.WRITE, function(err, connection) {
    if (err) return done('Database problem')

    connection.query('INSERT INTO comments (user_id, text, date) VALUES(?, ?, ?)', values, function(err, result) {
      if (err) return done(err)
      done(null, result.insertId)
    })
  })
}

exports.getAll = function(done) {
  db.get(db.READ, function(err, connection) {
    if (err) return done('Database problem')
      
    connection.query('SELECT * FROM comments', function (err, rows) {
      if (err) return done(err)
      done(null, rows)
    })
  })
}

exports.getAllByUser = function(userId, done) {
  db.get(db.READ, function(err, connection) {
    if (err) return done('Database problem')

    connection.query('SELECT * FROM comments WHERE user_id = ?', userId, function (err, rows) {
      if (err) return done(err)
      done(null, rows)
    })
  })
}

Tóm lại


Trong mỗi phương pháp, bạn chọn kết nối thích hợp cho ứng dụng của bạn, kết nối này đọc từ cơ sở dữ liệu được xây dựng có chủ đích. khi sử dụng Connection Pooling mysql thì hiệu suất được cải thiện đáng kể.


Bạn có thể tạo đối tượng kết nối proxy, đối tượng này dựa vào truy vấn có thể hiểu đây là truy vấn ghi hay đọc và sau đó chọn kết nối thích hợp. Bằng cách này, bạn thậm chí sẽ không thay đổi mô hình của mình trong tương lai nếu như có triển khai lớn một ứng dụng nào đó ngày từ lúc đầu.

ref:
https://www.terlici.com/
https://stackoverflow.com/questions/45068299/how-to-use-nodejs-cluster-with-mysql-pool-cluster

Có thể bạn đã bị missing