We are going to perform a simple test on reading and writing MongoDB, Redis, and Tokyo Tyrant. To perform a fair test, we need to understand the implementation mechanism behind them. Below are some comparisons:
Comparison of storage implementation:
* Memory File Image (Memory-File Mapping) Redis, MongoDB
* File + Cache Tokyo Tyrant
* Memory: Redis, Tokyo Tyrant
Key/Value index format:
* B + Tree: MongoDB, Tokyo Tyrant
* Hash Table: Redis, Tokyo Tyrant
* Fixed Length: Tokyo Tyrant
From the above comparison, we can see that Redis and MongoDB are based on the system memory image files. When the data hits the memory, the read/write operation performance should be very strong. Of course, in turn, if the data is scattered and cannot hit in the memory, the overhead of switching the memory page will be terrible. The difference between the MongoDB and Redis data files is that the data is stored in multiple files, A new data space file is created whenever the previous one is full. Because MongoDB is the main object to be compared, and it uses B + Tree for storage, TT also uses B + Tree engine for comparison.
So what should we test? We can naturally know that, although the memory image file read and write operations will be fast (to what extent), when the memory is full, what should we do?
File size limit:
32bit: MongoDB <= 2G
TT no limits if u./configure -- enable-off
64bit: MongoDB and TT are unrestricted.
Note: Redis is always limited by the memory size.
To perform a relatively fair test:
First, use the VM to limit the memory usage. Because MongoDB and Redi actually read and write data in the memory (using the MemoryMap file ), therefore, when the database size exceeds the memory size, the performance is particularly important. Therefore, a virtual machine is used to set a small memory size to quickly observe the performance when the database size exceeds the memory size.
The VM memory is set to 256 MB. The actual memory usage is about 9.10 MB. The CPU is 2 cores and the Unbuntu Server is.
Test records:
Key: a random string of 512
Value: a random string of about 5 kB.
Data size of each record: about 5.5 k
Insert 100000 data records: 5.5 k * 1000 = 5.5 M * 100 = 550 M data volume about 550 M.
Note: The key starts to be tested with a random string of 1 K. However, when the test mongoDB reports key too large to index, the size of the key is reduced to 512 bytes.
When no data exists:
MongoDB size:
64 M: (db.0, db.1,...) data FIle
16 M: (database. ns) name space index file.
TC size:
133 K btree. tcb
256 fixed. tcf
517 K hash. tch
Redis size:
VirtualMemFile: 41 M redis-3546.vm
DB: 0 M
Note: The initial size of the redis file is basically equal to the size of the configured memory and memory page. You can adjust the size by yourself. Redis saves data by means of the timed disk storage policy, which can be set by itself.
Generally, the redis database must <= memory. To make the redis database larger than the memory, you must enable the vm_enabled option in the configuration (it seems useless. When the data inserted exceeds the memory, will be killed by the Unbuntu background protection process. If the maximum memory usage is set, the new value cannot be inserted after the number of existing data records reaches the memory limit ).
Key/value functions:
Redis: read/write key/value, value can have various structures, but Value is not indexed.
MongoDB: organized by collection. If the key is not specified, it will be generated by the system as ObjectId (the "_ id" field is specified). The value is structured and the fields in the value can be indexed.
TokyoTyrant: read/write key/value. The table data engine supports structured value and field indexes. Other data engines do not support this function. B + tree can use key indexes.
Benchmark testing machine:
The virtual machine runs at 2 CPU 2.26G Intel Core 2 Duo with 2 GB memory
Virtual machine:
2-core CPU
Memory 256 MB
Operating system: Unbuntu Server 9.10 32bit
Software version:
* MongoDB: mongodb-linux-i686-2010-02-26
* TokyoTyrant: TT1.1.40; TC1.4.42
* Redis: 2010-03-01 (git src)
Start:
Redis-server./redis. conf (the maximum memory size is 210 MB: maxmemory 210000000, vm-enable = yes, vm-max-memory 20000000, vm-pages 1342177)
./Ttserver-port 1974/data/db/tt. tcb
Bin/mongod-port 1974 -- dbpath/data/db/mongo
MongoDB
Add 0.1 million pieces of data to the test as described above:
Memory: at the beginning, the virtual memory occupied 48564, and the physical memory occupied 3432. After 2000 pieces of data were inserted, the virtual memory reached 143 MB, and the physical memory was 33 MB. The memory increased rapidly. At last, the virtual memory is stable at 1048 MB, while the physical memory is at 160M-211M.
The minimum CPU usage is 6%, and the maximum CPU usage is 30%. The average CPU usage is between 8% and 10%.
From the test, when DB space is allocated each time, all the insert operations are frozen. The worst insert operation takes more than one minute (a space allocation file occurs at this time, it takes about 17-18 seconds to insert 2000 data records.
The total size of MongoDB data files reaches 977 mb.
Test MongoDB to read 0.1 million records (in the form of non-hit: The key is randomly generated, so most of the records will not exist in the database)
Memory: The virtual memory is stable at 1048 M, and the physical memory is occupied at 90 M-94 M.
CPU: The minimum CPU usage is 8%, and the maximum CPU usage is 45%-10%.
It takes about 3-4 seconds to read 2000 records. It takes 6 seconds to read the first record.
Redis
Add 0.1 million data entries in the same test:
Memory. I forgot to read it at the beginning. The initial virtual memory occupied 112 MB, and the physical memory was 82 mb. The VM occupied 40 thousand MB when there were 196 records, the physical memory usage is 163 MB. At last, the VM usage is 237 MB, and the physical memory usage is 204 MB.
CPU: The minimum CPU usage is 3%. The maximum CPU usage is 15%, which is usually between 7% and 11%.
When Redis writes data to the disk, it slows down (2000 records take 21 seconds). It usually takes about 18-19 seconds to store 2000 records.
However, when maxmemory is not set, the server is suspended after more than 60 thousand pieces of data are written. When the maximum memory usage (200 MB) is set, the memory limit is reached and cannot be written (48136 data records have been written.
The size of the Redis file when writing 48136 data (including VM files): 277 M, of which 41 M is VM and 236 M is database.
Then test Redis to read 0.1 million records (in the form of non-hit: most of the keys will not exist in the database)
Memory: 237 MB of virtual memory and 204 MB of physical memory
CPU: between 26% and 43%
It takes about 3-4 seconds to read 2000 records.
Tokyo Tyrant
Add 0.1 million pieces of data to the test as described above: use the default configuration parameter to run tt B + Tree
Memory: at the beginning, VM: 76928 physical memory: 1232. The memory size increases little during the insertion process. When 40 thousand records are inserted, the virtual memory is only 99540, and the physical memory is 23 MB, the final virtual memory is 117 M, and the physical memory is 37 M.
The CPU usage remains stable at 2%
Before inserting 50 thousand records, it takes about 2000 to 20 seconds to insert 80 thousand records. Before inserting 2000 records, it takes 20-22 seconds to insert the remaining 20 thousand records, the average insertion time of 2000 entries is slowly increasing and fluctuating. It takes 28 seconds and then 42 seconds (is the index node of B + Tree full in memory? You may need to adjust the parameter ?).
The TT database only has one File: 589 M
Then test TT to read 0.1 million records (in the form of non-hit: most of the keys will not exist in the database)
The memory is stable at: VM110M; the physical memory is 36 M.
CPU: minimum 2%, maximum 6%, usually at 4%
Reading 2000 records takes about 7-8 seconds, and occasionally 6 or 9 seconds.
Summary:
Data written to MongoDB and Redis is not directly written to the disk. Therefore, when the system is restarted, all data that is not stored on the disk will be lost. TT actually has a memory buffer, but it is much smaller than the former.
The above tests are not complete, but they are just the beginning. For example, there is no small data test (using numbers as the key, 100 bytes Value), and there is no big data test (about 20 kB ); performance in hit situations is not tested; concurrent read/write performance is not tested, it is reported that MongoDB's concurrent read/write efficiency is not particularly outstanding, and MongoDB features a powerful query language, its syntax is a bit similar to the object-oriented query language. It can almost implement a vast majority of functions similar to the single-table query of relational databases, and implement the automatic sharding management of storage nodes and other supporting functions; and because MongoDB is distributed in multiple files, when the data volume is large, the performance of the memory is distributed in enough files; the Replication test after the synchronization log is enabled .... for TT, we need to test other TT data engines and how to optimize various TT data engines? In the practical application of mixi, TC/TT stores more than 20 million pieces of data and supports tens of thousands of concurrent connections. It is a tested project. While ensuring high concurrent read/write performance, TC has a reliable data persistence mechanism and supports hashtable similar to the relational database table structure and simple conditions, paging and sorting operations, is a great NoSQL database. The main drawback of TC is That when the data volume reaches hundreds of millions, the performance of concurrent data writing will be greatly reduced (read is not affected). NoSQL: If Only It Was That Easy mentioned, they found that when 0.16 billion 2-20 KB data is inserted in TC, the write performance began to drop sharply. Redis is essentially a Key-Value type memory database, similar to memcached. The entire database is loaded into the memory for operations. The database data is regularly flushed to the hard disk for storage through asynchronous operations. Because it is a pure memory operation, Redis has excellent performance. The biggest charm of Redis is that it supports saving the data structure of the List linked List and Set, and also supports various operations on the List, for example, push and pop data from both ends of the List, get the List range, sort, etc. Set supports the union Set intersection operation of various sets. In addition, the maximum value of a single value is 1 GB, unlike memcached, which can only store 1 MB of data, Redis can be used to implement many useful functions. For example, it uses its List as a FIFO two-way linked List to implement a lightweight, high-performance Message Queue Service, the Set can be used as a high-performance tag system. In addition, Redis can also set the expire time for the Key-Value stored, so it can also be used as a functional enhanced version of memcached.