RE:NODE

ბაზები12 წუთის საკითხავი

MongoDB connection string: URI, mongosh და driver-ები

როგორ არის აგებული MongoDB URI: host-ები, authSource, percent-encoded პაროლები, mongodb+srv, pool-ის პარამეტრები, mongosh, Compass და ავტორიზაციის შეცდომები.

0 მკითხველი

MongoDB connection string ხუთნაწილიანი ერთი ხაზია და მასთან დაკავშირებული თითქმის ყველა პრობლემა მეოთხე ან მეხუთე ნაწილშია:

code
mongodb://appuser:s3cr3t@db.example.net:27017/shop?authSource=admin&retryWrites=true

Scheme, credentials, host და პორტი, ნაგულისხმევი მონაცემთა ბაზა, პარამეტრები. თუ კავშირი უარყოფილია, host ან პორტი არასწორია, ან სერვერი მისამართზე არ უსმენს, რომელსაც მიაღწევ. თუ ავტორიზაცია ვარდება მონაცემებით, რომლებიც სწორი გახსოვს, პასუხი თითქმის ყოველთვის authSource-ია ან პაროლი, რომელიც სიმბოლოს შეიცავს და percent-encoding სჭირდებოდა. ეს ორი MongoDB-ის კავშირის შესახებ დასმული კითხვების უმეტესობას ხსნის და ორივე URI-ში მოგვარდება და არა სერვერზე.

ეს პოსტი URI-ს ნაწილებად ყოფს, განიხილავს mongodb+srv-ს და როდის არ გამოდგება, პარამეტრებს, რომელთა დაყენებაც ღირს, როგორ დაუკავშირდე mongosh-ით, Compass-ით და Node-ისა და Python-ის driver-ებით, და რას ნიშნავს თითოეული გავრცელებული შეცდომა სინამდვილეში.

MongoDB URI-ს ანატომია#

ნაწილიმაგალითიშენიშვნები
Schememongodb://ან mongodb+srv:// DNS seed სიებისთვის
Credentialsappuser:s3cr3t@არჩევითია; ორივე percent-encode გააკეთე
Hostsdb.example.net:27017replica set-ისთვის მძიმით გამოყოფილი
ნაგულისხმევი მონაცემთა ბაზა/shopბაზა, რომელსაც driver იყენებს, თუ სხვას არ დაასახელებ
პარამეტრები?authSource=admin&-ით გამოყოფილი, გასაღებები რეგისტრზე არ არის დამოკიდებული

ორი მათგანი ყველაფერზე ადრე უფრო ახლოს დათვალიერებას საჭიროებს.

ნაგულისხმევი მონაცემთა ბაზა არის ის, რასაც driver აბრუნებს client.db()-დან არგუმენტის გარეშე, და, რაც უფრო მნიშვნელოვანია, ის authSource-ის ნაგულისხმევი მნიშვნელობაცაა. მისი გამოტოვება დასაშვებია: mongodb://user:pass@host:27017/?authSource=admin სრული URI-ა, ხოლო ?-მდე დახრილი ხაზი სავალდებულოა, თუ პარამეტრებს ბაზის დასახელების გარეშე გინდა.

host სია არის ადგილი, სადაც replica set-ები ცხადდება. mongodb://a:27017,b:27017,c:27017/?replicaSet=rs0 driver-ს სამი წევრის შესახებ ეუბნება; დანარჩენ ტოპოლოგიას driver თვითონ აღმოაჩენს, გაარკვევს, რომელია ამჟამად primary, და ცვლილებისას ჩაწერებს სხვაგან გადაამისამართებს. ერთ standalone სერვერზე არის ერთი host და replicaSet პარამეტრი არ არის, რაც ცალკე გაქირავებული მონაცემთა ბაზის სერვერის ჩვეულებრივი შემთხვევაა. RE:NODE-ზე standalone ხაზები არის PostgreSQL და MongoDB, რომლებთანაც გეგმაზე ნაჩვენები host-ითა და პორტით დაკავშირდები, superuser პაროლით, რომელიც ამ სერვერისთვის არის გენერირებული და არა გამოქვეყნებული ნაგულისხმევით, ამიტომ შენი პირველი URI არის ეს host, ეს პორტი და ეს credentials.

პაროლები, percent-encoding და შეცდომა, რომელსაც არავინ ელის#

URI არის URI, ამიტომ მომხმარებლის სახელში ან პაროლში ნებისმიერი სიმბოლო, რომელსაც მასში მნიშვნელობა აქვს, percent-encode უნდა გაკეთდეს. გენერირებული პაროლები მათით სავსეა.

სიმბოლოდაშიფრული
:%3A
/%2F
?%3F
#%23
[ და ]%5B და %5D
@%40
%%25

პაროლი p@ss/w0rd ხდება p%40ss%2Fw0rd. თუ გამოტოვებ, driver ან მაშინვე აგდებს Password contains unescaped characters-ს, ან, უარესი, ყველაფერს, რაც ცალკე @-ის შემდეგ მოდის, ჩუმად hostname-ად კითხულობს და იტყობინება, რომ სერვერს სახელად ss/w0rd ვერ პოულობს.

ხელით ნუ დაშიფრავ. ყველა ენას აქვს ფუნქცია:

javascript
const uri = `mongodb://${encodeURIComponent(user)}:${encodeURIComponent(pass)}@db.example.net:27017/shop?authSource=admin`;
python
from urllib.parse import quote_plusuri = f"mongodb://{quote_plus(user)}:{quote_plus(pw)}@db.example.net:27017/shop?authSource=admin"

კიდევ უკეთესია credentials სტრიქონში საერთოდ არ ჩასვა და driver-ს ცალკე არგუმენტებად გადასცე, რასაც driver-ების უმეტესობა უჭერს მხარს. მაშინ დასაშიფრი არაფერია და log-ში, რომელიც URI-ს ბეჭდავს, გასაჟონი არაფერი.

mongodb:// თუ mongodb+srv://#

mongodb+srv:// სხვა პროტოკოლი არ არის. ეს მალსახმობია, რომელიც driver-ს ეუბნება, host სია DNS-ში მოძებნოს და არა სტრიქონიდან წაიკითხოს. mongodb+srv://db.example.net/-ის შემთხვევაში driver ითხოვს SRV ჩანაწერს _mongodb._tcp.db.example.net hostname-ებისა და პორტებისთვის, შემდეგ კი TXT ჩანაწერს db.example.net-ზე ისეთი ნაგულისხმევი პარამეტრებისთვის, როგორიცაა replicaSet და authSource.

სამი შედეგი, რაც ხალხს ბნევს:

  • +srv URI-ში პორტს ვერ ჩასვამ. პორტები SRV ჩანაწერებიდან მოდის.
  • hostname ზუსტად ერთი უნდა იყოს და SRV ჩანაწერები უნდა არსებობდეს. +srv-ის ჩვეულებრივ host-ზე მიმართვა გაძლევს querySrv ENOTFOUND _mongodb._tcp.db.example.net-ს.
  • +srv TLS-ს ნაგულისხმევად რთავს. სერვერი, რომელიც TLS-ისთვის არ არის გამართული, handshake-ს უარყოფს და შეცდომა TLS-ს იშვიათად ახსენებს.

ასე რომ: mongodb+srv:// გამოიყენე, როცა შენმა პროვაიდერმა +srv სტრიქონი მოგცა, რაც ჩვეულებრივ ნიშნავს მართულ cluster-ს, რომლის წევრობა შეიძლება შეიცვალოს. ჩვეულებრივი mongodb:// host-ითა და პორტით გამოიყენე სერვერისთვის, რომელსაც ცალკე ქირაობ. თუ ამ host-ის წინ მეგობრული სახელი გინდა, მისამართზე მიმართული A ჩანაწერი საქმეს SRV-ის მექანიკის გარეშე აკეთებს - DNS ჩანაწერები ახსნილი ფარავს, რომელი ჩანაწერი გამოიყენო.

only for +srvhost listdirect host and porton first useauthenticatedConnection URIscheme and optionsDNS lookupSRV then TXTConnection poolmaxPoolSize 100SCRAM handshakeuses authSourcemongodTCP 27017
როგორ აქცევს driver URI-ს ავტორიზებულ კავშირად

authSource, მომხმარებლები და როლები#

MongoDB-ის მომხმარებლები გლობალური არ არის. ყოველი მომხმარებელი კონკრეტულ მონაცემთა ბაზაშია შექმნილი და მას ეკუთვნის, ამ ბაზის სახელი კი არის ის, რასაც authSource ნიშნავს. superuser თითქმის ყოველთვის admin-შია, ამიტომ URI, რომელიც სხვა ნაგულისხმევ ბაზას ასახელებს, ამას უნდა ამბობდეს:

code
mongodb://root:pw@db.example.net:27017/shop?authSource=admin

authSource=admin-ის გარეშე driver shop-ში ეძებს მომხმარებელს სახელად root, ვერ პოულობს და ვარდება Authentication failed-ით, შეცდომის კოდი 18. credentials არასოდეს ყოფილა არასწორი. როცა authSource მითითებული არ არის, ის URI-ში მოცემულ ბაზაზე ნაგულისხმევდება; როცა URI-ში ბაზაც არ არის, ნაგულისხმევია admin.

აპლიკაციისთვის superuser-ს ნუ გამოიყენებ. შექმენი მომხმარებელი, რომელიც მხოლოდ იმ ერთ ბაზას ეხება, რომელიც სჭირდება:

javascript
use admindb.createUser({  user: "shopapp",  pwd: passwordPrompt(),  roles: [ { role: "readWrite", db: "shop" } ]})

admin-ში შექმნილი და shop-ით შეზღუდული როლის მქონე მომხმარებელი უკავშირდება authSource=admin-ით და shop-ის გარეთ ვერაფერს აკეთებს. თუ ის shop-ში შექმენი, URI იყენებს authSource=shop-ს; ორივე სწორია, ერთი კონვენციის არჩევა და მისი დაცვა კი შემდგომში მთელ შუადღეს გიზოგავს.

როლები, რომელთა ცოდნაც ღირს: read და readWrite ერთი ბაზისთვის, dbAdmin ინდექსებისა და სტატისტიკისთვის, readWriteAnyDatabase ინსტრუმენტისთვის, რომელსაც ყველაფერს უნდა შეეხოს, და root superuser-ისთვის. backup ამოცანას სჭირდება backup; მონიტორინგის შემოწმებას - clusterMonitor. თითოეულ დაკავშირებულ რამეს საკუთარი მომხმარებელი მიეცი, რადგან სწორედ ეს ხდის სერვერის log-სა და db.currentOp()-ს სასარგებლოს, როცა რამე არასწორად მუშაობს. ამ არგუმენტის უფრო ფართო ვერსია არის მონაცემთა ბაზის უსაფრთხოების checklist-ში.

დაკავშირება mongosh-ით და Compass-ით#

mongosh არის მიმდინარე shell; ძველი mongo binary MongoDB 6.0-ში ამოიღეს. ის იღებს ან სრულ URI-ს, ან ცალკე ფლაგებს:

bash
$ mongosh "mongodb://shopapp@db.example.net:27017/shop?authSource=admin"$ mongosh --host db.example.net --port 27017 \      -u shopapp -p --authenticationDatabase admin shop

პაროლი გამოტოვე და დაუშვი, რომ მოგთხოვოს. command line-ზე აკრეფილი ის shell-ის ისტორიაში და პროცესების სიაში ხვდება, სადაც მანქანაზე მყოფ ნებისმიერ სხვა მომხმარებელს შეუძლია მისი წაკითხვა.

შიგნით ოთხი ბრძანება გეუბნება, სად ხარ:

javascript
db.runCommand({ connectionStatus: 1 })   // who am I, and with what rolesdb.getName()                             // which database am I inshow dbs                                 // what can I seedb.serverStatus().connections            // current, available, totalCreated

mongosh ასევე არაინტერაქტიულად მუშაობს, რაც მას cron ამოცანაში ან deploy სკრიპტში სასარგებლოს ხდის. mongosh "$MONGODB_URI" --quiet --eval 'db.orders.countDocuments()' ბეჭდავს ერთ რიცხვს და გადის; mongosh "$MONGODB_URI" --file migrate.js უშვებს ფაილს. ორივე არანულოვან exit status-ს აბრუნებს, როცა სკრიპტი შეცდომას აგდებს, ამიტომ set -e-სთან ისე მუშაობს, როგორც გინდა. ეს სკრიპტები idempotent შეინახე, რადგან მათი მეორედ გაშვება ჩვეულებრივ სწორედ ის დროა, როცა ეს მნიშვნელოვანია.

Compass, ოფიციალური GUI, იმავე URI-ს იღებს თავის კავშირის ველში. ის მას ველებად შლის, რაც კარგი გზაა იმის შესამოწმებლად, სწორად არის თუ არა აგებული სტრიქონი, რომელიც მოგცეს, და კავშირების ფავორიტებად შენახვაც შეუძლია. მას აქვს SSH tunnel tab-იც, რაც სწორი პასუხია, როცა მონაცემთა ბაზა ინტერნეტში საერთოდ არ უნდა იყოს გამოტანილი და მასთან მანქანით მიდიხარ, რომელსაც ამის უფლება აქვს. ყველაფერი, რასაც Compass აკეთებს, mongosh-საც შეუძლია, ამიტომ shell ხელთ გქონდეს იმ მომენტებისთვის, როცა GUI თავდაჯერებულად ცდება.

კავშირის პარამეტრები, რომელთა დაყენებაც ღირს#

პარამეტრინაგულისხმევირას აკეთებს
authSourceURI-ის ბაზა, სხვა შემთხვევაში adminსად შეიქმნა მომხმარებელი
retryWritestrueქსელის შეფერხების შემდეგ ჩაწერას ერთხელ იმეორებს
wmajority MongoDB 5.0+-ზერამდენმა წევრმა უნდა დაადასტუროს ჩაწერა
readPreferenceprimaryსად მიდის წაკითხვები replica set-ზე
maxPoolSize100კავშირები, რომლებსაც ეს client თითო სერვერზე გახსნის
minPoolSize0უმოქმედობისას ღია დარჩენილი კავშირები
maxIdleTimeMSარ არის დაყენებულიხურავს ამაზე დიდხანს უმოქმედო კავშირებს
serverSelectionTimeoutMS30000რამდენ ხანს ეძებს გამოსადეგ სერვერს ჩავარდნამდე
connectTimeoutMS30000TCP connect timeout
socketTimeoutMSარ არის დაყენებულინუ შეეხები, თუ არ იცი რატომ
appNameარ არისლეიბლი, რომელიც სერვერის log-სა და currentOp-ში ჩანს
tlsfalse, true +srv-ითაშიფრავს კავშირს
compressorsარ არისzstd, zlib ან snappy wire პროტოკოლისთვის

სამი პრაქტიკული შენიშვნა. maxPoolSize=100 თითო client-ზე გულუხვია; პატარა აპლიკაცია ოთხი worker პროცესით სერვერს, რომელსაც შეიძლება რამდენიმე ასეული მეგაბაიტი მეხსიერება ჰქონდეს, შესაძლო ოთხას კავშირს აცხადებს. დააყენე ისეთი მნიშვნელობა, რომელზეც დაფიქრებული ხარ - 10-დან 20-მდე თითო პროცესზე უმეტესი დატვირთვისთვის საკმარისია, და მსჯელობა ზოგადდება პოსტში connection pool-ები და ლიმიტები.

serverSelectionTimeoutMS ნაგულისხმევი ოცდაათი წამით არის მიზეზი, რის გამოც არასწორად გამართული URI ჩავარდნის ნაცვლად გაჭედვას ჰგავს. დეველოპმენტში მისი 5000-ზე დაწევა ოცდაათწამიან საიდუმლოს მყისიერ, იოლად წასაკითხ შეცდომად აქცევს.

და appName=checkout-api არაფერი ღირს და პირველივე ჯერზე იხდის თავს, როცა სერვერის log-ს უყურებ და გინდა იცოდე, შენი რომელი სერვისის მოთხოვნას დასჭირდა ცხრა წამი.

ორი პარამეტრი standalone სერვერზე საერთოდ არაფერს აკეთებს და ღირს იმის ცოდნა, რომელი. readPreference replica set-ის წევრებს შორის ირჩევს, ამიტომ secondaryPreferred ერთ სერვერზე უბრალოდ იმ ერთადერთ სერვერს კითხულობს. w=majority ასევე ეცემა "ერთმა node-მა დაადასტურა" დონეზე. არცერთი არ არის მავნებელი, მაგრამ არცერთი არ არის ის გამძლეობა ან წაკითხვის გაფართოება, რაც გგონია, რომ იყიდე, და მათი დაყენება backup-ის შემცვლელი არ არის. standalone instance-ზე გამძლეობის რეალური კონტროლი journaling-ია, რომელიც ნაგულისხმევად ჩართულია და მოკლე ინტერვალით flush-ს აკეთებს, წაკითხვის გაფართოების რეალური კონტროლი კი ინდექსია, რომელიც მოთხოვნას მილიონი დოკუმენტის წაკითხვისგან იცავს.

Driver-ები: ერთი client, ხელახლა გამოყენებული#

შეცდომა, რომელიც MongoDB-ის წარმადობაზე ჩივილების უმეტესობას იწვევს, თითო მოთხოვნაზე client-ის შექმნაა. MongoClient არის pool, ტოპოლოგიის monitor და ფონური thread-ების ნაკრები. ის განკუთვნილია, რომ პროცესის დაწყებისას ერთხელ შეიქმნას და პროცესის სიცოცხლის განმავლობაში გაზიარდეს. ის thread-safe-ია და უსაფრთხოა async ამოცანებს შორის გასაზიარებლად; fork-ს გავლით გაზიარებისთვის უსაფრთხო არ არის.

javascript
import { MongoClient } from "mongodb";const client = new MongoClient(process.env.MONGODB_URI, {  maxPoolSize: 20,  serverSelectionTimeoutMS: 5000,  appName: "checkout-api",});await client.connect();const shop = client.db("shop");export const orders = shop.collection("orders");
python
from pymongo import MongoClientclient = MongoClient(    os.environ["MONGODB_URI"],    maxPoolSize=20,    serverSelectionTimeoutMS=5000,    appName="checkout-api",)orders = client["shop"]["orders"]

ორივე client ზარმაცად უკავშირდება: პირველ ოპერაციამდე ქსელში არაფერი ხდება, ამიტომ არასწორი URI გაშვებისას კარგად შეიძლება ჩანდეს და პირველ მოთხოვნაზე ჩავარდეს. თუ გაშვებისას გინდა იცოდე, ping გააგზავნე health check-ის ნაწილად:

javascript
await client.db("admin").command({ ping: 1 });

ეს readiness probe-ის სწორი სხეულიც არის, რადგან ის ადასტურებს, რომ pool-ს შეუძლია სერვერამდე მიღწევა და ავტორიზაცია, რაც "მონაცემთა ბაზა მუშაობს"-ის რეალური მნიშვნელობაა.

სტრიქონის repository-სგან მოშორება#

URI შეიცავს პაროლს, ამიტომ ის საიდუმლოა და გარემოში უნდა იყოს და არა კოდის ხეში:

.env
MONGODB_URI=mongodb://shopapp:p%40ss@db.example.net:27017/shop?authSource=admin

აქედან გამომდინარე ოთხი წესი, რომლებიც მოსაწყენია გარკვეული მიზეზით. .env შეინახე .gitignore-ში და დააკომიტე .env.example ფორმით, მაგრამ მნიშვნელობების გარეშე. staging-ისთვის სხვა მომხმარებელი და სხვა ბაზა გამოიყენე, ვიდრე production-ისთვის, რომ არასწორად გამართულმა staging deploy-მ რეალურ მონაცემებზე ვერ დაწეროს. URI credentials-ის მოცილებით დაბეჭდე ან საერთოდ ნუ დაბეჭდავ, რადგან შეცდომის handler, რომელიც connection string-ს ბეჭდავს, პაროლს სამუდამოდ შენს log aggregator-ში ათავსებს. და პაროლი შეცვალე, როცა ვინმე მიდის, რაც რეალისტურია მხოლოდ მაშინ, თუ აპლიკაცია მას ერთი ადგილიდან კითხულობს. გარემოს ცვლადები და საიდუმლოები გადის, სად უნდა იყოს ეს მნიშვნელობები.

ექსპოზიცია იმდენადვე მნიშვნელოვანია, რამდენადაც პაროლი. მონაცემთა ბაზას, რომელსაც მთელი ინტერნეტიდან წვდება და მისაწვდომი მომხმარებელი, scanner-ები საათებში პოულობენ, ხოლო ავტორიზაციის გარეშე მყოფ MongoDB instance-ებში აღმოჩენილი გამოსასყიდის შეტყობინებების კოლექციები მითი არ არის. დარწმუნდი, რომ ავტორიზაცია მართლა ჩართულია, თუ შეგიძლია, შეზღუდე, საიდან შეიძლება კავშირები, და სატესტო instance ნაგულისხმევი კონფიგურაციით არასოდეს დატოვო.

შეცდომები და რას ნიშნავს ისინი სინამდვილეში#

`Authentication failed` (კოდი 18) - არასწორი authSource ბევრად უფრო ხშირად, ვიდრე არასწორი პაროლი. შეამოწმე, რომელ ბაზაში შეიქმნა მომხმარებელი, შემდეგ სცადე იგივე credentials mongosh-ში --authenticationDatabase-ით.

`MongoServerSelectionError` / `ServerSelectionTimeoutError` - driver-მა serverSelectionTimeoutMS-ის განმავლობაში სერვერი ვერ იპოვა. credentials-თან კავშირი არ აქვს. არასწორი host, არასწორი პორტი, სერვერი მისაწვდომ მისამართზე არ უსმენს, ან firewall.

`connect ECONNREFUSED 203.0.113.10:27017` - ამ მისამართზე ვიღაცამ უპასუხა და უარი თქვა. ჩვეულებრივ სერვერი მხოლოდ 127.0.0.1-ზეა მიბმული, რაც MongoDB 3.6-იდან ნაგულისხმევია.

`querySrv ENOTFOUND _mongodb._tcp.example.net` - +srv URI, რომელიც host-ზე მიუთითებს SRV ჩანაწერების გარეშე. გამოიყენე mongodb:// პორტით.

`Password contains unescaped characters` - percent-encode გააკეთე, როგორც ზემოთ.

`command find requires authentication` - დაკავშირებული ხარ, მაგრამ ანონიმურად. credentials URI-ში არ იყო, ან driver-ს მიეცა ბაზა, რომელიც authSource არ არის.

`Unsupported OP_QUERY command` - driver სერვერზე ძველია და პროტოკოლს ლაპარაკობს, რომელიც MongoDB 5.1-ში ამოიღეს. განაახლე driver-ის პაკეტი.

FAQ#

რა არის authSource და რატომ მჭირდება?

ის ასახელებს მონაცემთა ბაზას, რომელშიც მომხმარებლის ანგარიშია, და ეს აუცილებლად არ არის ბაზა, რომელშიც მუშაობა გინდა. Superuser-ები ჩვეულებრივ admin-შია, ამიტომ აპლიკაციის ბაზაზე მიმართულ URI-ს მათ საპოვნელად authSource=admin სჭირდება. თუ არასწორად დაწერ, სრულიად სწორი credentials-ით ავტორიზაციის ჩავარდნას ნახავ.

რა განსხვავებაა mongodb:// და mongodb+srv://-ს შორის?

mongodb+srv:// სერვერების სიას DNS-ს ეკითხება და არა URI-დან კითხულობს, და TLS-ს ნაგულისხმევად რთავს. მას SRV ჩანაწერები უნდა არსებობდეს და პორტი ვერ ექნება. ერთი standalone სერვერისთვის ჩვეულებრივი mongodb:// host-ითა და პორტით სწორი ფორმაა.

შემიძლია MongoDB-სთან browser-იდან დაკავშირება?

არა. MongoDB ლაპარაკობს ბინარულ wire პროტოკოლზე TCP-ით და არა HTTP-ით, ამიტომ კავშირს შენი სერვერული კოდი აწყობს. სწორედ ამიტომ არ აქვს მონაცემთა ბაზის გეგმას reverse proxy წინ: არაფერი იქნებოდა, რასაც ის გაატარებდა. შენი აპლიკაცია პორტზე უკავშირდება, browser კი შენს აპლიკაციას ესაუბრება.

მჭირდება თუ არა TLS ჩემს connection string-ში?

თუ ტრაფიკი საჯარო ინტერნეტს კვეთს, დიახ, და სერვერი ჯერ ამისთვის უნდა იყოს გამართული. ერთი მანქანის შიგნით, სადაც აპლიკაცია და მონაცემთა ბაზა ერთ host-ზეა და ბაზა მხოლოდ loopback მისამართს უსმენს, ის არაფერს ამატებს. tls=true-ს ჩართვა სერვერზე, რომელიც ამისთვის არ არის გამართული, handshake-ზე ვარდება.

რამდენი კავშირი უნდა გახსნას ჩემმა აპლიკაციამ?

ბევრად ნაკლები, ვიდრე ნაგულისხმევი 100 თითო client-ზე. დაიწყე 10-დან 20-მდე თითო პროცესზე, გაამრავლე პროცესების რაოდენობაზე და შედეგი შეადარე db.serverStatus().connections-ს. ყოველი ღია კავშირი სერვერზე მეხსიერებას ხარჯავს, ამიტომ იმედით შერჩეული pool პატარა instance-ის მეხსიერების ამოწურვის გზაა.

სად წავიდე შემდეგ?

როგორც კი დაკავშირდები, ორი რამ წყვეტს, ბაზა სწრაფი დარჩება თუ არა: დოკუმენტების ფორმა და რომელი ინდექსები არსებობს - იხილე MongoDB schema design და ინდექსები. სანამ რამე რეალურს ჩადებ, წაიკითხე mongodump და mongorestore და გააკეთე backup, რომელიც მინიმუმ ერთხელ აღგიდგენია.


კომენტარები

სრულიად ანონიმურად: ანგარიშის, ელფოსტის და cookie-ის გარეშე. ინახება მხოლოდ სახელი, ტექსტი და დრო - სხვა არაფერი. ბმულების რაოდენობა ლიმიტირებულია.

0/2000