2009-07-10 14 views
5

Tôi đang phát triển một ứng dụng web nhiều bên thuê bằng cách sử dụng LAMP. Tất cả dữ liệu phiên người dùng của tôi hiện được lưu trữ trong mysql với loại bảng InnoDB.Cách tiếp cận bảng phiên MySQL

Có cách nào để tôi có thể sử dụng loại bảng NHỚ (thường dùng) để lưu các phiên hiện tại và sử dụng chức năng thu gom rác của trình xử lý phiên để di chuyển phiên giữa InnoDB (bảng thông thường) và (trong) Bảng MEMORY?

Cấu hình này cũng sẽ ảnh hưởng đến bất kỳ cách nào khi tôi muốn phân cụm & cấu hình chính-nô lệ ở giai đoạn sau?

Cảm ơn trước, ocptime

Trả lời

6

Viết một custom session handler là đáng ngạc nhiên dễ dàng, nhưng tôi nghĩ rằng có nhiều cách có lẽ tốt hơn để lưu trữ dữ liệu phiên hơn MEMORY bảng.

Một cái gì đó giản đồ như (nâng lên với những thay đổi từ a previous question)

CREATE TABLE IF NOT EXISTS `session` (
    `id` char(32) NOT NULL, 
    `data` varchar(20000) NOT NULL, 
    `time_created` timestamp NOT NULL default '0000-00-00 00:00:00', 
    `time_updated` timestamp NOT NULL default '0000-00-00 00:00:00' on update CURRENT_TIMESTAMP, 
    PRIMARY KEY (`id`), 
    KEY `time_created` (`time_created`), 
    KEY `time_updated` (`time_updated`) 
) ENGINE=MEMORY DEFAULT CHARSET=utf8; 

sau đó bạn muốn chỉ phải xác định các chức năng điều khiển phiên của bạn, như được nêu trong diễn đàn hoặc trong tutorial này. Nếu bạn muốn lưu thông tin phiên trong quá trình thu gom rác, bạn chỉ cần tạo một bảng giống với bảng ở trên bằng cách sử dụng công cụ INNODB và thêm một chút vào cuối hàm gc() sao chép hàng từ các bảng MEMORY đến INNODB.

Tuy nhiên MEMORY bảng có một số giới hạn khá đáng kể. Họ không thể sử dụng các cột BLOB hoặc TEXT - đó là lý do tại sao tôi có số này xấu xí varchar(20000) ở trên. Chúng có kích thước tối đa 16 MB. Nếu bạn có nhiều người dùng, giữ nhiều trạng thái hoặc gặp sự cố với việc thu thập rác, bạn có thể đạt đến giới hạn và sự cố đó.

Ý tưởng tốt hơn là sử dụng memcache session handler, đặc biệt nếu bạn không cần lưu trữ thông tin phiên vào tương lai xa. Tôi khá chắc chắn memcached là nhanh hơn bất kỳ RDBMS sẽ được (ngay cả với MEMORY bảng) và nó cũng quy mô theo thiết kế. Ngoài ra, bạn sẽ không phải viết các hàm xử lý phiên của riêng bạn.

+1

Có thể tăng kích thước bảng tối đa bằng cách điều chỉnh biến hệ thống [max_heap_table_size] (https://dev.mysql.com/doc/refman/5.5/en/server-system-variables.html#sysvar_max_heap_table_size). –

3
InnoDB: ~40 milliseconds Cons: (Slowest) 
MEMORY: ~22 milliseconds Cons: (16MB Max) 
MyISAM: ~25 milliseconds Cons: (Table-level locking) 

Tôi đang sử dụng (gs), vì vậy tôi không thể làm memcache, nhưng đó sẽ là tốt nhất. Cá nhân tôi đang cân nhắc sử dụng MEMORY, nhưng tôi không biết liệu lợi ích hiệu suất có vượt quá chi phí giới hạn kích thước hay không. Vì vậy, tôi đã làm những gì mọi lập trình viên giỏi nên làm khi tối ưu hóa: tôi đã lược tả nó.

trang php của tôi trong câu hỏi được lưu trữ trong smarty, vì vậy các hoạt động chỉ xảy ra ở đây là một tra cứu regex trên url và một phiên lấy sql để kiểm tra nếu người dùng đang đăng nhập.

Dù sao đây là kết quả : Với InnoDB tôi đã nhận được ~ 40 mili giây chờ đợi một yêu cầu. (Tôi đo điều này trong chrome với các công cụ phát triển.) Sau khi chuyển đổi bảng thành MEMORY tôi nhận được ~ 20 mili giây cho mỗi yêu cầu. wow! Cải thiện 50%! Nhưng hãy đợi ... còn MyISAM thì sao? Tôi đã thử điều đó và tôi nhận được ~ 22-23 mili giây cho mỗi yêu cầu. Oh.

Đây chỉ là tôi thử nghiệm nó, không phải là một ứng dụng quy mô đầy đủ.Một ứng dụng thực tế sẽ có hàng ngàn người viết vào bảng đó mỗi giây, và MyISAM thực hiện khóa cấp bảng, điều này có thể xấu (Which MySQL database engine is better for storing sessions and session data: MyISAM or InnoDB?).

Vì vậy, tôi hiện đang gắn bó với bộ nhớ. Đó là một cải tiến lớn cho những trang được lưu trong bộ nhớ cache, nhưng tôi khuyến khích bạn sử dụng hồ sơ! Nếu trang web của bạn đang xây dựng lại mọi trang, thì 10 mili giây có thể không thực sự quan trọng.

+0

Cách khóa cấp bảng sẽ ảnh hưởng đến hiệu suất trên ứng dụng quy mô lớn hơn. Nó sẽ chặn người dùng một cách hiệu quả khi ai đó cố ghi vào phiên như đăng nhập? – Lightbulb1

+0

@ Lightbulb1, * mọi * lượt xem trang phải cập nhật bảng phiên trên cơ sở dữ liệu để cập nhật thời gian truy cập cuối cùng (để biết khi nào hết hạn phiên và khi phiên được miễn phí để thu gom rác). Nếu hai người nhận được một trang tại cùng một thời điểm chính xác thì một người phải chờ cho đến khi người khác viết xong vì Mysql chặn cho đến khi viết xong (trừ khi bạn làm [LOW_PRIORITY] (http: //dev.mysql .com/doc/refman/5.0/en/update.html) cập nhật, sẽ khắc phục sự cố). Điều này thực sự chỉ là tối ưu hóa sớm. Nếu trang web của bạn là bận rộn xem xét memcached. – andychase

+0

Cảm ơn bạn đã cung cấp thông tin. Tôi đã không sử dụng memcache trước vì vậy một cái gì đó mà tôi cần phải làm nghiên cứu thêm về. Nó đúng cách sẽ là giải pháp cho tương lai. – Lightbulb1

0

Sử dụng bảng InnoDB cho phiên. Tôi đã nghe nói rằng bảng bộ nhớ trong khi chèn khóa toàn bộ bảng trong khi InnoDB chỉ khóa hàng cụ thể cần được điều khiển.