简体   繁体   中英

How should I set up mongodb cluster to handle 20K+ simultaneous

My application uses MongoDB as database. We are expecting 20K+ simultaneous connections to mongodb cluster. How should I config the server if I want to run the mongodb on 20 servers and shard the cluster 20 ways?

Here is what I've done so far: On each of my 20 servers, I have one mongos (router) running on port 30000, and on 3 servers I run mongo config servers on port 20000. Then on each server, I run 3 instances of mongod. One of the is the primary. In order words, I have 20 mongos, 3 mongo-config, 60 mongod servers (20 primary and 40 replica).

Then in my application (which also run on each server and connect to the localhost:30000 mongos), I set the mongoOptions such that the connectionsPerHost = 1000.

10-15 minutes after all services start, some of them became no longer ssh-able. These servers are still ping-able. I suspect there were too many connections, and it caused the server to die.

My own analysis is as follows: 1K connections per connection pool means for each shard's primary, it will have 1K * 20 (shards) = 20K simultaneous connections open. A few servers will probably have more than one primary running on it, which will double or triple the number of connections to 60K. Somehow mongod cannot handle these many connections although I changed my system settings to allow each process to open way more files.

Here are what 'ulimit -a' shows:

core file size (blocks, -c) 0
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 20
file size (blocks, -f) unlimited
pending signals (-i) 16382
max locked memory (kbytes, -l) 64000000
max memory size (kbytes, -m) unlimited
open files (-n) 320000
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) 819200
real-time priority (-r) 0
stack size (kbytes, -s) 8192
cpu time (seconds, -t) unlimited
max user processes (-u) unlimited
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited

BTW, I didn't specify --maxConns when I start up mongod/mongos, I also didn't change MONGO.POOLSIZE.

A side question: if my reasoning is correct, the total number of simultaneous connection requirement will be posed on each primary, which doesn't seem right to me, it almost means mongodb cluster is not scalable at all. Someone tell me I'm wrong please?

Sometimes the limits don't apply to the process itself. As a test go onto one of the servers and get the pid for the mongo service you want to check on by doing

ps axu | grep mongodb

and then do

cat /proc/{pid}/limit

That will tell you if the limits have taken effect. If the limit isn't un effect then you need to specify the limit in the startup file and then stop - start the mongo service and test again.

A sure-fire way to know if this is happening is to tail -f the mongo log on a dying server and watch for those "too many files" messages.

We set our limit to 20000 per server and do the same on all mongod and mongos instances and this seems to work.

Aout your cluster architecture :

Running several instances of mongod on the same server is usually not a good idea, do you any particular reason to do this ? The primary server of each shard will put some heavy pressure on your server, the replication also add io pressure, so mixing them won't be really good for performance. IMO, you should rather have 6 shards (1 master - 2 secondaries) and give each instance their own server. (Conf and arbiter instance are not very resources consomming so its ok to leave them on the same servers).

We're running a 4-shard replicaset on 4 machines. We have 2 shard primaries on 2 hosts, 2 shard replicas on the other 2 boxes, arbiters and config servers spread out).

We're getting messages:

./checkMongo.bash: fork: retry: Resource temporarily unavailable
./checkMongo.bash: fork: retry: Resource temporarily unavailable
./checkMongo.bash: fork: retry: Resource temporarily unavailable
Write failed: Broken pipe 

Checking ulimit -a:

core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 773713
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) unlimited
open files                      (-n) 4096
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 10240
cpu time               (seconds, -t) unlimited
max user processes              (-u) 1024
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited   

Okay, so we're possibly hitting a process limit because of the fork message. Here's how to check that:

$ ps axo pid,ppid,rss,vsz,nlwp,cmd | egrep mongo
27442     1 36572   59735772 275 /path/mongod --shardsvr --replSet shard-00 --dbpath /path/rs-00-p --port 30000 --logpath /path/rs-00-p.log --fork
27534     1 4100020 59587548 295 /path/mongod --shardsvr --replSet shard-02 --dbpath /path/rs-02-p --port 30200 --logpath /path/rs-02-p.log --fork
27769     1 57948   13242560 401 /path/mongod --configsvr --dbpath /path/configServer_1 --port 35000 --logpath /path/configServer_1.log --fork

So, you can see the mongod's have 275, 295, and 401 subprocesses/threads each. though I'm not hitting a limit now, I probably was earlier. So, the solution: change the system's ulimit for the user we're running under from 1024 to 2048 (or even unlimited). You can't change via

ulimit -u unlimited

unless you sudo first or something; I don't have privs to do that.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM