ÎÒÒ»Ö±ÖÂÁ¦ÓÚѰÕÒ¸üºÃµÄ´ð°¸¡£Ê×ÏÈ£¬ÎÒÖÆ¶¨ÁË¡¶·þÎñÆ÷·¢ÏÖÓë¼à¿Ø¹æ·¶£¨Server
Discovery and Monitoring Spec£©¡·¡ª¡ªÏÖÔÚÒÑÓ¦ÓÃÓÚÎÒÃÇËùÓеÄÇý¶¯ÉÏ£¬´Ë¹æ·¶¼«´óµØÌáÉýÁËÇý¶¯ÔÚÓ¦¶ÔÍøÂç´íÎóºÍ·þÎñÆ÷¹ÊÕÏ×ªÒÆÊ±µÄÎȽ¡ÐÔ£¬ÓÉÓÚÇý¶¯³ÌÐòµÄÒì³£×´¿ö¼õÉÙ£¬ÀàËÆIanÕâÑùµÄ±§Ô¹Ò²Óú·¢º±¼ûÁË¡£´ËÍ⣬ÓÉÓÚËùÓÐÇý¶¯µÄ±íÏÖÓ¦µ±ÊÇÒ»Öµģ¬ÎÒÃÇ¿ÉÒÔʹÓñê×¼»¯µÄ³£¹æ²âÊÔÌ×¼þÀ´Ö´Ðмì²â¡£
Ëæºó£¬ÎÒ¿ª·¢ÁËÒ»ÖÖ±»³ÆÎª¡°ºÚ¹Ü²âÊÔ¡±£¨Black Pipe Testing£©µÄ¼¼Êõ£¬ÕâÑùIan¾Í¿ÉÒÔ¼ì²âËûµÄ´úÂëÔÚÓëMongoDB½»»¥Ê±£¬ÈçºÎÓ¦¶ÔÍøÂç¹ÊÕÏ¡¢Ö¸Áî´íÎóµÈʼþÁË¡£ºÚ¹Ü²âÊÔ±ã½ÝÓÖÄܶ¨ÐÔ£¬Äܹ»ÇáËÉÖØÏÖ²¢²âÊÔ´íÎó¡£
ÏÖÔÚ£¬ÎÒÃÇÄܹ»»Ø´ðIanµÄÎÊÌâÁË¡£Èç¹ûÏÖÔÚËûµ½ÎÒÃÇλÓÚʱ´ú¹ã³¡µÄ´ó°ì¹«ÊÒÀ´ÌáÎÊ£¬Äã»áÈçºÎ»Ø´ð£¿ÈçºÎ±àдµ¯ÐÔMongoDBÓ¦Óã¿
ÃæÁÙµÄÌôÕ½
ÎÒÃÇ»á¸æËßIanµ¯ÐÔÖ´ÐÐupdateOneµÄ·½·¨£º
updateOne({'_id': '2016-06-28'}, {'$inc': {'counter': 1}}, upsert=True) |
ͨ¹ý¼ÆËãÎĵµÖС°counter¡±×ֶεĵÝÔö£¨ÒÔµ±ÌìÈÕÆÚΪid£©£¬À´¼ÆËãʼþ·¢ÉúµÄ´ÎÊý¡£¶ÔÓÚµ±ÈյĵÚÒ»¸öʼþ£¬Óá°upsert=True¡±´´½¨Îĵµ¡£
DZÔÚÎÊÌâ
ÔÝ̬´íÎó£¨Transient errors£©
Ò»µ©IanÏòMongoDB·¢ËÍupdateOneÐÅÏ¢£¬Çý¶¯³ÌÐò¿ÉÄÜ»á²ì¾õÍøÂç²ãµÄÔÝ̬´íÎó£¬ÀýÈçÒ»´ÎTCPÖØÖûòÊÇÒ»´Î³¬Ê±¡£
ÔÝÌ¬ÍøÂç´íÎó¡¢¹ÊÕÏ×ªÒÆ»ò·þÎñÆ÷Çл»£¨stepdown£©

Çý¶¯³ÌÐòÎÞ·¨È·ÈÏ·þÎñÆ÷ÊÇ·ñÒѽÓÊÕµ½ÐÅÏ¢£¬Òò´ËIanÒ²ÎÞ´Ó²éÑécounterÊÇ·ñÓеÝÔö¡£
ÆäËüÔÝ̬´íÎóÀàËÆÓÚÍøÂç¶ÌÔÝÖжϣ¨network blip£©¡£Èç¹ûÖ÷·þÎñÆ÷̱»¾£¬ÔòÇý¶¯³ÌÐòÏÂÒ»´ÎÊÔͼÏòÆä·¢ËÍÐÅϢʱ£¬»á²úÉúÍøÂç´íÎó¡£¼øÓÚ¸±±¾¼¯¼¸ÃëÄÚ¾ÍÄÜÑ¡³öеÄÖ÷·þÎñÆ÷£¬ËùÒԸôíÎóºÄʱ½Ï¶Ì¡£Óë´ËÀàËÆ£¬ÈôÖ÷·þÎñÆ÷Çл»£¨¸Ã·þÎñÆ÷ÈÔÈ»ÔËÐУ¬µ«²»Ôٳе£Ö÷·þÎñÆ÷Ö°Ô𣩣¬Ôò»áÇжÏËùÓÐÁ¬½Ó¡£¼ÙÈçÏÂÒ»´ÎÇý¶¯³ÌÐòÈÔ½«ÐÅÏ¢·¢Ë͵½Ö®Ç°µÄÖ÷·þÎñÆ÷£¬¾Í»áµ¼ÖÂÍøÂç¹ÊÕÏ£¬»ò·þÎñÆ÷µÄ¡°not
master£¨·ÇÖ÷£©¡±»Ø¸´¡£
ÉÏÊöËùÓÐÇé¿öÖУ¬Çý¶¯³ÌÐò¶¼»áÏòIanµÄÓ¦ÓÃÅ׳öÒ»¸öÁ¬½Ó´íÎó¡£
ÓÀ¾ÃÐÔ´íÎó
»¹ÓпÉÄÜ»á³öÏÖÓÀ¾ÃÐÔµÄÍøÂçÖжϣºÎÊÌâÔÚÊ״α»¼ì²âµ½Ê±ÀàËÆÓÚ¶ÌÔÝÖжϣ¨Çý¶¯³ÌÐò·¢³öÐÅϢȴÎÞÏìÓ¦£©¡£
ÓÀ¾ÃÐÔÍøÂçÖжÏ

ÈçÉÏËùÊö£¬Ian²»ÄÜÈ·¶¨·þÎñÆ÷ÊÇ·ñ½ÓÊÕµ½ÐÅÏ¢£¬ÒÔ¼°counterÓзñµÝÔö¡£
Çø·Ö¶ÌÔÝÖжÏÓëå´»úµÄ¹Ø¼üÔÚÓÚ£ºÇ°ÕßÇé¿öÏ£¬Öظ´²Ù×÷Ö»»áµ¼ÖÂеÄÍøÂç´íÎó²úÉú£¬µ«ÏëҪȷÈϱØÐë¾¹ý³¢ÊÔ¡£
ÃüÁî´íÎó
Çý¶¯³ÌÐò·¢³öÒ»ÌõÐÅÏ¢ºó£¬MongoDB¿ÉÄܻ᷵»ØÄ³¸ö´íÎ󣬱íʾÒÑÊÕµ½ÃüÁÎÞ·¨Ö´ÐУ¬Ò²ÐíÊÇÒòΪÃüÁî¸ñʽ´íÎó£¬Ò²ÐíÊÇÒòΪ·þÎñÆ÷´ÅÅ̿ռ䲻×㣬»òÊÇÒòΪӦÓóÌÐòδ»ñÊÚȨ¡£
ÃüÁî´íÎó

×ÛÉÏËùÊö£¬ÕâÈýÀà´íÎó½ÏÄѷֱ棬ÇÒÐèÒªÔÚ´úÂëÖÐдÈ벻ͬµÄ»ØÓ¦£¬ÄÜ·ñ¸ø³öÒ»¸öÖÇÄܵĽâ¾ö·½°¸£¬ÁîIanµÄÓ¦Óþ߱¸µ¯ÐÔÄØ£¿
ÊÇ·ñÒòΪÎÒÃÇûÓÐÊÂÎñ£¿
ÒòΪ²»°üº¬ÊÂÎñ£¬Äã¿ÉÄܻỳÒÉÕâÊÇMongoDBÌØÓеÄÎÊÌâ¡£¼ÙÉèIanʹÓô«Í³µÄSQL·þÎñÆ÷£¬Ëû¿ªÆôÊÂÎñ¡¢¸üÐÂÄÚÈݲ¢·¢ËÍCOMMIT
message£¬Í»È»³öÏÖÍøÂçÔÝʱÖжϣ¬²¢ÇÒÎÞ·¨´Ó·þÎñÆ÷»ñµÃÈ·ÈÏ¡ª¡ªÔÚÕâÖÖÇé¿öÏ£¬IanÄÜ·ñÈ·ÈÏÊÂÎñÒѾÌá½»ÁËÄØ£¿

ͨ¹ýSQL·þÎñÆ÷½øÐС°Ç¡Ò»´Î¡±²Ù×÷£¬ºÍͨ¹ýMongoDBÕâÑùµÄ·ÇÊÂÎñÐÔ·þÎñÆ÷½øÐвÙ×÷£¬¶¼»áÔâÓöÏàͬµÄÎÊÌâ¡£
MongoDBÇý¶¯ÈçºÎ´¦Àí¹ÊÕÏ
ÔÚÖÆ¶¨ÖÇÄܽâ¾ö·½°¸Ç°£¬Ê×ÏÈÒªÇå³þMongoDBÇý¶¯³ÌÐò¶Ô¸÷Àà´íÎóµÄÏìÓ¦·½Ê½¡£
¡¶·þÎñÆ÷·¢ÏÖÓë¼à¿Ø¹æ·¶¡·ÒªÇóMongoDBÇý¶¯³ÌÐò¸ú×Ùÿһ¸öÓëÆäÁ¬½ÓµÄ·þÎñÆ÷״̬¡£±ÈÈ磬Ëü¿ÉÄÜ»áÕâÑùÕ¹ÏÖÒ»¸öÈý½ÚµãµÄ¸±±¾¼¯£º
Server 1: Primary
Server 2: Secondary
Server 3: Secondary
ÕâÖÖÊý¾Ý½á¹¹±»³ÆÎª¡°ÍØÆË½á¹¹¡±¡£Èç¹ûÔÚÓë·þÎñÆ÷¶Ô»°Ê±·¢ÉúÍøÂç´íÎó£¬Çý¶¯³ÌÐò»á½«¸Ã·þÎñÆ÷ÀàÐÍÉèÖÃΪ¡°Î´Öª¡±£¬ËæºóÅ׳öÒì³£¡£ÕâÖÖÇé¿öϵÄÍØÆË½á¹¹ÈçÏ£º
Server 1: Unknown
Server 2: Secondary
Server 3: Secondary
IanµÄ²Ù×÷²»»á×Ô¶¯ÖØÊÔ£¬µ«ÔÚÇý¶¯³ÌÐòÖØÐ·¢ÏÖÖ÷·þÎñÆ÷֮ǰ£¬ºóÃæµÄ²Ù×÷ÎÞ·¨½øÐС£Çý¶¯ÒÔÿÃëÁ½´ÎµÄƵÂÊÖØÐ¼ì²é·þÎñÆ÷£¬¹ý³Ì³ÖÐø30Ã룬ֱµ½ÓëÖ÷·þÎñÆ÷»ò¼ì²âµ½ÐÂÑ¡³öµÄÖ÷·þÎñÆ÷ÖØÐÂÁ¬½Ó¡£Ä¿Ç°MongoDBÑ¡ÔñзþÎñÆ÷Ö»ÐèÒªÏûºÄ1ÖÁ2Ã룬֮ºó0.5ÃëÄÚÇý¶¯¾ÍÄÜ·¢ÏÖÐÂÑ¡³öµÄÖ÷·þÎñÆ÷¡£
ÁíÒ»·½Ã棬Èô³ÖÐøÖжϳ¬¹ý30Ã룬Çý¶¯³ÌÐò»áÅ׳ö¡°·þÎñÆ÷Á¬½Ó³¬Ê±¡±µÄÒì³£¡£
ÃüÁî´íÎóʱ£¬Çý¶¯³ÌÐò»áÈÏΪ¸Ã·þÎñÆ÷ûÓб仯¡ª¡ªÎÞÂ۸÷þÎñÆ÷ÊÇÖ÷·þÎñÆ÷»¹ÊǶþ¼¶·þÎñÆ÷£¬¼ÌÐø±£³ÖÔÑù¡£ÕâÑùÒ»À´£¬ÔÚÍØÆË½á¹¹ÖУ¬Çý¶¯³ÌÐò²»»á¸Ä±ä·þÎñÆ÷״̬£¬Ö»»áÅ׳öÒì³£¡£
£¨ÏëÒªÁ˽â¸ü¶à¹ØÓÚ¡¶·þÎñÆ÷·¢ÏÖÓë¼à¿Ø¹æ·¶¡·µÄÄÚÈÝ£¬¿ÉÔĶÁÎÒµÄÁíһƪÎÄÕ¡¶Server Discovery
And Monitoring In PyMongo, Perl, And C¡·£¬»òÕßä¯ÀÀÎÒÔÚMongoDB
World 2015´ó»áÉÏ·¢±íµÄÑÝ˵£¬Ö÷ÌâΪ¡°MongoDB Drivers and High Availability:
A Deep Dive¡±¡£ÆäÖÐÎÒÏêϸ½²ÊöÁ˹淶ÖÐËùÃèÊöµÄÊý¾Ý½á¹¹£¬ÒÔ¼°°´Õոù淶Çý¶¯³ÌÐòÓ¦µ±ÈçºÎ¶Ô´íÎó×ö³öÏìÓ¦¡£ÕâΪ±¾Îĵĵ¯ÐÔÓ¦ÓÃÌṩÁ˷ḻµÄÏà¹Ø±³¾°ÖªÊ¶²¹³ä¡££©
²»µ±µÄÖØÊÔ·½°¸
²¿·Ö°¸Àý£º
²»½øÐÐÖØÊÔ
ĬÈϲ»ÖØÊÔ£º¸Ã²ßÂÔµÄʧ°Ü¸ÅÂÊΪÈý·ÖÖ®Ò»¡£

³öÏÖÔÝÌ¬ÍøÂç´íÎóʱ£¬Ian¸ø·þÎñÆ÷·¢ËÍÐÅÏ¢£¬µ«²»ÄÜÈ·¶¨·þÎñÆ÷ÊÇ·ñÊÕµ½¸ÃÐÅÏ¢¡£ÈôûÓнÓÊÕµ½£¬Ôòʼþ묒Êý£¬Ò²Ðí´úÂëÖлá¼Ç¼¸Ã´íÎó£¬È»ºó¼ÌÐøÖ´ÐвÙ×÷¡£
ÓÐȤµÄÊÇ£¬¶ÔÓÚ³¤ÆÚµÄÍøÂçÖжϻòÖ¸Áî´íÎ󣬡°²»ÖØÊÔ¡±·´¶øÊÇÕýÈ·µÄÑ¡Ôñ£¬ÒòΪ¶ÔÓÚ·ÇÔÝ̬´íÎó£¬ÖØÊÔ²»»áÓÐÈκνá¹û¡£
×ÜÊÇÖØÊÔ
һЩ³ÌÐòÔ±ÔÚ±àд´úÂëʱ£¬ÒªÇó½«ËùÓÐʧ°ÜµÄ²Ù×÷ÖØÊÔÎå´ÎÄËÖÁÊ®´Î£¬ºÜ¶àʵ¼ÊÓ¦ÓÃÖж¼ÓÐÕâÑùµÄ°¸Àý¡£
i = 0 while True: try: do_operation() break except network error: i += 1 if i == MAX_RETRY_COUNT: throw |
È¥Ä꣬ÎÒÓëRackspaceµÄÒ»Ãû¹¤³ÌʦSam̸¼°´ËÊ£¬ËûÑØÓÃÁËÒ»¸öPython´úÂë¿â£¬²¢Êµ¼ùÁËÕâ¸ö²»Á¼·½°¸£ºÒ»µ©²¶»ñÒì³£¾Í»á·´¸´ÖØÊÔ¡£
SamÒѾ·¢ÏÖÕâ¸ö·½°¸ÓÐÎó£¬Ëû×¢Òâµ½ÎÒÒÀ¾Ý¡¶·þÎñÆ÷·¢ÏÖÓë¼à¿Ø¹æ·¶¡·ÖØÐ±àдÁËPyMongoµÄ¿Í»§¶Ë´úÂ룬²¢Ï£ÍûʹÓÃÎȽ¡ÐÔ¸üÇ¿µÄÐÂÇý¶¯¡£SamÖ»ÖªµÀ»¹´æÔÚ¸üºÃµÄÖØÊÔ·½°¸£¬µ«²»ÄÜÈ·ÇеØÕÒ³öÀ´¡£Êµ¼ÊÉÏ£¬ÕýÊǺÍËûµÄÕâ¶Î̸»°ÈÃÎÒÃÈ·¢ÁËд×÷ÕâÆªÎÄÕµÄÄîÍ·¡£
Sam·¢ÏÖÁËʲô£¿ÎªÊ²Ã´Ian²»Ó¦µ±É趨ÿÏî²Ù×÷ÖØÊÔÎå´ÎÉõÖÁÊ®´Î£¿

ÍøÂçÔÝʱÖжÏʱ£¬Ian²»ÔÙÓмÆÊýÒÅ©µÄ·çÏÕ£¬·´¶øÒª¿¼ÂÇÖØ¸´¼ÆÊýµÄÎÊÌ⣬ÒòΪÈç¹û·þÎñÆ÷ÔÚÍøÂç´íÎó·¢Éúǰ¶ÁÈ¡Á˵ÚÒ»ÌõupdateOneÐÅÏ¢£¬µÚ¶þÌõÐÅÏ¢»áµ¼Ö¼ÆÊýÔÙ´ÎÔö¼Ó¡£
ÁíÒ»·½ÃæÔÚ³ÖÐøÖжÏʱ£¬¶à´ÎÖØÊÔ»áÀË·Ñʱ¼ä¡£µÚÒ»´ÎÍøÂç´íÎóÖ®ºó£¬Çý¶¯³ÌÐò»á½«Ö÷·þÎñÆ÷±ê¼Ç³É¡°Î´Öª¡±£»IanÖ´ÐÐÖØÊÔ²Ù×÷ºó£¬Çý¶¯³ÌÐò»á³¢ÊÔÖØÁ¬£¬Ëø¶¨ºóÐø²Ù×÷²¢ÔÚÖ®ºóµÄÈýÊ®ÃëÄÚ±£³ÖÿÃëÁ½´ÎµÄ¼ì²éƵÂÊ¡£Èç¹ûÈ«²¿Ê§°Ü£¬´úÂë»áÔÙ´ÎÖØÊÔ£¬Í½À͵ØÖ´ÐÐÖØÊÔÑ»·£¬´Ó¶øÔì³ÉÓ¦ÓÃÎÞ¹ÊÑÓ³Ù¡£
ÃüÁî´íÎóÒ²ÊÇͬÑù£ºÈôIanµÄÓ¦ÓÃδ¾ÊÚȨ£¬³¢ÊÔÎå´ÎÒ²²»»áÓÐËù¸Ä±ä¡£
¶ÔÍøÂç´íÎóÖØÊÔÒ»´Î
µ½Ä¿Ç°ÎÒÃÇÒѾ¿ìµÃ³öÖÇÄÜ·½°¸ÁË¡£Ó¦¶ÔÍøÂç´íÎóµÄ³õ´Î²Ù×÷ʧ°Üºó£¬Ian²»ÄÜÈ·¶¨¸Ã´íÎóÊÇÔÝ̬µÄ»¹ÊdzÖÐøµÄ£¬Òò´ËÖ»ÖØÊÔÁËÒ»´Î£¬Õâ´ÎÖØÊÔ½øÈëÁËÇý¶¯³ÌÐòµÄ30ÃëÖØÊÔÑ»·¡£Èô¸ÃÍøÂç´íÎó³ÖÐø30Ã룬Ôò¿ÉÄÜ»á³ÖÐø¸ü¾Ã£¬ËùÒÔIan·ÅÆú¼ÌÐøÖØÊÔ¡£
È»¶ø£¬Ãæ¶ÔÃüÁî´íÎóÍêÈ«ÎÞÐèÖØÊÔ¡£

ÏÖÔÚֻʣÏÂÒ»¸öÎÊÌ⣺IanÓ¦µ±ÈçºÎ¹æ±Ü¼ÆÊý¹ý¶ÈµÄÎÊÌ⣿
ÖØÊÔÍøÂç´íÎ󣬽øÐÐÃݵȲÙ×÷
ÃݵȲÙ×÷µÄÌØµãÊÇ£º¶à´ÎÖ´ÐÐÓëÒ»´ÎÖ´ÐеĽá¹ûÏàͬ¡£ÈôIanµÄ²Ù×÷È«ÊÇÃݵȵģ¬¾Í¿ÉÒÔ°²È«ÖØÊÔ£¬ÎÞÐèµ£ÐĹý¶È¼ÆÊý£¬»òÒòÐÅÏ¢ÖØ¸´·¢ËͶøÔì³ÉÊý¾Ý´íÎó¡£

Transient network err Persistent outage Command error
Correct Correct Correct
Òò´Ë£¬ÈçºÎʹupdateOneÐÅÏ¢²Ù×÷ÃݵȻ¯ÄØ£¿
ÃݵȲÙ×÷
MongoDBÓÐËÄÀà²Ù×÷£ºfind£¨²éÕÒ£©¡¢insert£¨²åÈ룩¡¢delete£¨É¾³ý£©ºÍupdate£¨¸üУ©£¬Ç°ÈýÀàÒ×ÓÚÃݵÈÐÔ£¬ÎÒÃÇÏÈÀ´´¦Àí£º
Find²Ù×÷
²éѯÊÇÌìÈ»Ãݵȵģº
try: doc = findOne() except network err: doc = findOne() |
¼ìË÷Ò»¸öÎĵµÁ½´ÎºÍÒ»´ÎµÈЧ¡£
Insert²Ù×÷
±È²éѯÉÔÀ§ÄÑһЩ£¬µ«Ò²²»ÊÇÌØ±ðÀ§ÄÑ¡£
doc = {_id: ObjectId(), ...} try: insertOne(doc) except network err: try: insertOne(doc) except DuplicateKeyError: pass # first try worked throw |
ÔÚpseudo-PythonÖУ¬µÚÒ»²½»áÉú³É¿Í»§¶ËµÄΨһID¡£MongoDBµÄObjectIdsÕýÊÇרÃÅΪ´ËÉè¼ÆµÄ£¬µ«ÈκÎΨһֵ¶¼ÄÜ×öµ½¡£
ÏÖÔÚ£¬Ian³¢ÊÔ²åÈëÎĵµ¡£Èô¸Ã½ø³ÌÒòÎªÍøÂç´íÎó¶øÊ§°Ü£¬ÔòÖØÊÔ¡£Èô¶þ´Î³¢ÊÔÓÖÒòΪ·þÎñÆ÷µÄduplicate
key errorÎÊÌâ¶øÔÙ´Îʧ°Ü£¬ËæºóµÚÒ»´Î³¢ÊԳɹ¦£¬ÔòËû½öÒòÍøÂç²ã´íÎó¶øÎÞ·¨¶ÁÈ¡·þÎñÆ÷ÏìÓ¦¡£Èç¹û³öÏÖÆäËü´íÎó£¬ÔòÈ¡Ïû²Ù×÷²¢Å׳öÒì³£¡£
²åÈëÊÇÃݵȲÙ×÷¡£Î¨Ò»ÐèҪעÒâµÄÊÇ£º´Ë´¦¼Ù¶¨Ian³ýÁËMongoDB×Ô¶¯´´½¨µÄone on _idÖ®Í⣬ÔÚcollectionÉÏûÓÐÆäËüΨһË÷Òý¡£ÈôÓУ¬ÄÇôËû±ØÐë½âÎöduplicate
key error£ºÈôÔÚÆäËüË÷ÒýÖУ¬ÔòÓ¦ÓÿÉÄÜ´æÔÚbug¡£
Delete²Ù×÷
ÈôIanʹÓÃΨһ¼üֵɾ³ýÒ»¸öÎĵµ£¬ÔòÁ½´Î²Ù×÷ºÍÒ»´Î²Ù×÷µÈЧ¡£
try: deleteOne({'key': uniqueValue}) except network err: deleteOne({'key': uniqueValue}) |
ÈôµÚÒ»´Î²Ù×÷Ö´ÐÐÍê±Ïʱ£¬·¢ÉúÍøÂçÒì³££¬Ian½øÐÐÖØÊÔ£¬Ôò¶þ´Îɾ³ýΪ¿Õ²Ù×÷£¨no-op£©£¬ËüÎÞ·¨ÕÒµ½Æ¥ÅäÎĵµ¡£É¾³ý²Ù×÷ÖØÊÔÊǰ²È«µÄ¡£
Ö´ÐдóÁ¿ÎĵµÉ¾³ý¸üΪ¼òµ¥£º
try: deleteMany({...}) except network err: deleteMany({...}) |
ÈôIan¶ÔÈ«²¿É¸Ñ¡³öµÄÎĵµÖ´ÐÐɾ³ý£¬µ«Í¬Ê±³öÏÖÍøÂç´íÎó£¬ÊÇ¿ÉÒÔ°²È«ÖØÊԵġ£ÎÞÂÛdeleteOneÖ´ÐÐÒ»´Î»¹ÊÇÁ½´Î£¬½á¹û¶¼ÊÇÏàͬµÄ¡ª¡ªËùÓÐɸѡ³öµÄÎĵµ¶¼±»É¾³ý¡£
ÔÚÉÏÊöÁ½¸ö°¸ÀýÖж¼´æÔÚ¾ºÌ¬Ìõ¼þ£ºÁ½´Îɾ³ý²Ù×÷¼äÓвåÈëÆ¥ÅäÎĵµµÄ½ø³Ì£¬µ«ÎÞÂÛÈçºÎ¶¼±Èѹ¸ù²»ÖØÊÔÒªºÃ¡£
Update²Ù×÷
ÖÁÓÚ¸üвÙ×÷£¬ÎÒÃÇÏÈ´Ó×ÔÈ»ÃݵÈÀàÐÍ¿ªÊ¼ÌÖÂÛ¡£
# Idempotent update. updateOne({ '_id': '2016-06-28'}, {'$set':{'sunny': True}}, upsert=True) |
Óë×î³õµÄÀý×Ó²»Í¬£¬ÕâÀïIanûÓÐÔö¼Ó¼ÆÊý£¬Ö»Êǽ«µ±Èյġ°sunny£¨ÇçÀÊ£©¡±×Ö¶ÎÉèÖÃΪTrue£¬¶øÉèÖÃÁ½´ÎÓëÒ»´ÎЧ¹ûÏàͬ¡£ÔÚÕâÖÖÇé¿öÏ£¬updateOneµÄÖØÊÔÊǰ²È«µÄ¡£
Ò»°ãÔÔòÏ£¬MongoDBµÄijЩupdate²Ù×÷ÊÇÃݵȵģ¬ÓÐЩ²»ÊÇ¡£$setÊÇÃݵȵģ¬ÒòΪ¾ÍËãÖØ¸´ÉèÖã¬Ö»ÒªÉèÖÃΪÏàͬµÄÖµ£¬½á¹ûÊÇÒ»ÑùµÄ£¬¶ø$incÔòÊÇ·ÇÃݵȵġ£
Èç¹ûIanµÄ¸üвÙ×÷ÊÇÃݵȵģ¬Ôò¿É¼òµ¥µØÖ´ÐÐÖØÊÔ£ºÊ״γ¢ÊÔÈô·¢ÉúÍøÂçÒì³££¬Ôò¿ÉÖØÐ²Ù×÷£¬·Ç³£¼òµ¥¡£
try: updateOne({' _id': '2016-06-28'}, {'$set':{'sunny': True}}, upsert=True) except network err: try again, if that fails throw |
ÏÂÃæÊÇ×îÀ§ÄѵݸÀý£¬×î³õµÄ·ÇÃݵȲÙ×÷updateOne£º
updateOne({ '_id': '2016-06-28'}, {'$inc': {'counter': 1}}, upsert=True) |
ÈôIanżȻ²Ù×÷ÁËÁ½´Î£¬Ôò¼ÆÊýÔöÖÁ2¡£
ÈçºÎ½«Õâ¸ö²Ù×÷ת»¯ÎªÃݵȲÙ×÷£¿¿ÉÒÔ·ÖΪÁ½²½£¬·Ö±ðÖ´ÐÐÃݵȲÙ×÷£¬Í¨¹ý½«Õâ¸ö²Ù×÷ת»¯ÎªÁ½²½£¨ÃݵȲÙ×÷£©£¬¾ÍÄܰ²È«Ö´ÐÐÖØÊÔÁË¡£
Ê×ÏÈ£¬ÉèÎĵµ¼ÆÊýֵΪN:
{ _id: '2016-06-28', counter: N } |
²½ÖèÒ»£º²»´¦ÀíN£¬Ian½öÏòÒ»¸ö¡°pending¡±Êý×éÖмÓÈëÒ»¸ötoken¡£ÕâʱËûÐèҪij¸ö¾ßÓÐΨһÐԵĶ«Î÷£¬±ÈÈçÒ»¸öObjectId¡£
oid = ObjectId() try: updateOne({ '_id': '2016-06-28'}, {'$addToSet': {'pending': oid}}, upsert=True) except network err: try again, then throw |
$addToSetÊÇÒ»ÖÖÃݵȲÙ×÷£¬¾ÍËãÖ´ÐÐÁ½´Î£¬tokenÒ²Ö»»á¼ÓÈëÊý×éÒ»´Î¡£´ËʱÎĵµÈçÏ£º
{ _id: '2016-06-28', counter: N, pending: [ ObjectId("...") ] } |
²½Öè¶þ£ºIan½ö¸ù¾ÝÒ»ÌõÐÅÏ¢£¬Í¨¹ýÆä_idºÍpending token²éѯÎĵµ£¬É¾³ýpending token£¬Ôö¼Ó¼ÆÊý¡£
try: # Search for the document by _id and pending token. updateOne({'_id': '2016-06-28', 'pending': oid}, {'$pull': {'pending': oid}, '$inc': {'counter': 1}}, upsert=False) except network err: try again, then throw |
ËùÓÐMongoDBµÄ¸üвÙ×÷£¬ÎÞÂÛÊÇ·ñÃݵȣ¬¶¼ÊÇÔ×Ó¼¶±ðµÄ¡ª¡ªµ¥¸öupdateOne²Ù×÷ÈôûÓÐÍêÈ«³É¹¦£¬Ôò³¹µ×ÎÞЧ¡£Òò´ËÈô½«token´ÓpendingÊý×éÖÐÒÆ³ý£¬Ôò¼ÆÊý»áÇÒ½ö»áÔö¼Ó1¡£
½«Õâ¸öupdateOne²Ù×÷ÊÓΪһ¸öÕûÌ壬ÔòËüÊôÓÚÃݵȲÙ×÷¡£¼ÙÉèIan½«tokenÒÆ³öÊý×飬²¢ÔÚ³õ´Î³¢ÊÔ²Ù×÷ʱÔö¼Ó¼ÆÊý£¬µ«ÓÉÓÚÍøÂç´íÎóûÄܶÁÈ¡·þÎñÆ÷µÄ·´À¡¡£ÔòÒòΪ²éѯÎĵµËùÐèµÄpending
tokenÒѱ»ÒƳý£¬ËùÒÔ¶þ´Î³¢ÊÔΪ¿Õ²Ù×÷¡£
Òò´ËIan¿É°²È«ÖØÊÔ¸ÃupdateOne²Ù×÷¡£ÎÞÂÛÖ´ÐÐÒ»´Î»¹ÊÇÁ½´Î£¬Îĵµ×îÖÕ¶¼ÊÇÏàͬµÄ£º
{ _id: '2016-06-28', counter: N + 1, pending: [ ] } |
ÈÎÎñÍê³ÉÁËÂð£¿
ÏÖÔÚÈÎÎñÒÑÍê³É£º½«IanµÄ³õʼupdateOne²Ù×÷£¨ÖØÊÔ²»°²È«£©Í¨¹ý·ÖÀë³ÉÁ½¸ö²½ÖèµÄ·½Ê½£¬×ª»¯ÎªÃݵȲÙ×÷¡£
ÕâÏî¼¼ÊõÓÐһЩÐèҪעÒâµÄµØ·½£¬ÆäÖÐÖ®Ò»ÊÇ£ºÈç½ñIan¼òµ¥µÄÔö¼Ó²Ù×÷ÐèÒªÁ½´ÎÕÛ·µ£¬ÕâÒâζ×ÅÑӳٺ͸ºÔض¼»á¼Ó±¶¡£Èç¹ûÕâ¸öʼþÉټƻòÕß¶à¼ÆÒ»´Î¶¼Ã»¹ØÏµ£¬¸ÕÇÉËûµÄÅóÓѱ»ÍøÂçÏßÀÂ°íµ¹£¨¸ÅÂʼ«µÍ£©£¬ÄÇôËû²»Ó¦Ê¹Óøü¼Êõ¡£
ÁíÒ»¸ö×¢ÒâµãÊÇ£ºËûÐèҪÿÌìÍíÉÏÖ´ÐÐÒ»¸öÇåÀí½ø³Ì¡£Ë¼¿¼Ò»Ï£ºÈôµÚ¶þ²½Ò»Ö±Ã»ÄÜÍê³É»áÔõÑù¡£
try: updateOne({'_id': '2016-06-28', 'pending': oid}, {'$pull': {'pending': oid}, '$inc': {'counter': 1}}, upsert=False) except network err: try again, then throw |
¼ÙÉèÍøÂçÖжϷ¢ÉúÔÚIanÌí¼Ópending tokenÖ®ºó£¬ÒƳýtoken²¢Ôö¼Ó¼ÆÊý֮ǰ£¬ÔòÎĵµ´¦ÓÚÈçÏÂ״̬£º
{ _id: '2016-06-28', counter: N, pending: [ ObjectId("...") ] } |
IanÐèÒªÔÚÍíÉÏÖ´ÐÐÇåÀíÈÎÎñ£¬ÕÒ³öµ±ÈÕʧ°ÜÈÎÎñËùÒÅÁôµÄpending token£¬²¢Íê³ÉÆä¼ÆÊý¸üС£ÎªÁ˱ÜÃâ²¢·¢ÎÊÌ⣬IanÒ»Ö±µÈµ½Ò»Ìì½áÊø£¬²»ÔÙÓнø³ÌÖ´Ðе±ÈյļÆÊý¸üÐÂʱ¡£Ëûͨ¹ý¾ÛºÏ¹ÜµÀ£¨aggregation
pipeline£©ÕÒ³ö´øÓÐpending tokenµÄÎĵµ£¬²¢Ïòµ±Ç°¼ÆÊýÔö¼ÓÊý×Ö£º
pipeline = [{ '$match': {'pending.0': {'$exists': True}} }, { '$project': { 'counter': { '$add': [ '$counter', {'$size': '$pending'} ] } } }] for doc in collection.aggregate(pipeline): collection.updateOne( { '_id': doc._id}, { '$set': {'counter': doc.counter}, '$unset': {'pending': True} }) |
¶ÔÓÚÿ¸ö¾ÛºÏ½á¹û£¬ÕâÏîÈÎÎñ»áʹÓÃ×îÖÕ¼ÆÊýÀ´¸üÐÂÔ´Îĵµ£¬²¢Í¨¹ýÖØÖÃÀ´ÇåÀípendingÊý×é¡£
ÒòΪʹÓÃÁËÃݵȲÙ×÷$setºÍ$unset£¬updateOne²Ù×÷ÔÚÖØÊÔʱÊǰ²È«µÄ¡£ÎÞÂÛÍøÂç×´¿öÈçºÎ£¬Ian¶¼¿ÉÖØ¸´ÖØÊÔÖ´ÐÐÇåÀíÈÎÎñÖ±µ½³É¹¦¡£ÓÐÁËÇåÀíÈÎÎñÖ®ºó£¬Ianµ±ÈÕʼþµÄ×îÖÕ¼ÆÊýÊÇÕýÈ·µÄ¡£
ÈôIan¿ÉÒÔ½ÓÊÜÕâЩ£ºÔö¼Ó¼ÆÊýÐèÒªÁ½´ÎÕÛ·µ£¬ÇÒ¿ÉÄܻᵽµ±ÈÕ½áÊø²ÅÄÜÍê³É£¬ÄÇô¶ÔÓÚijЩ¼ÛÖµ½Ï¸ßµÄ²Ù×÷£¬ÕâÏî¼¼ÊõÊÇ׼ȷÔö¼Ó¼ÆÊýµÄµ¯ÐÔ²ßÂÔ¡£
µ¯ÐÔ¼ì²â 
ÎÒÃÇÌṩÁ˲ßÂÔ£¬µ«IanÈÔÈ»²»ÂúÒ⡪¡ªËû¸ÃÈçºÎ¼ì²âÊÇ·ñÒѾͨ¹ý´úÂëÕýȷʵÏÖÁËÄØ£¿Îª´ËÎÒÌá³öÁË¡°ºÚ¹Ü²âÊÔ¡±¼¼Êõ¡£
ÔÚ½øÐкںÐ×Ó²âÊÔʱ£¬ÎÒÃÇÊäÈëÊýÖµ£¬µÃ³ö½á¹û£¬Õâ¸ö¹ý³Ì¾ÍÏñÊÇÓÿ¾Ãæ°ü»ú¿¾Ãæ°üÒ»Ñù¡£µ«ÕâЩºÚºÐ²âÊÔ²»»áµ¼ÖÂÍøÂç´íÎó¡¢³¬Ê±¡¢ÖжϻòÃüÁî´íÎó¡£Ä£ÄâÍøÂç²ã»á¸üºÃһЩ£¬µ«ÈôÍøÂç²ã±¾Éí´æÔÚbug£¬ÄǾÍÖ»ÄÜÑÚ¸ÇÕâЩbug¡£
Òò´ËÎÒ×ܽá³öÁ˺ڹܲâÊÔ£ºÊ¹ÓÃÕæÊµµÄÍøÂç·þÎñÆ÷ÓëMongoDB Wire Protocol¶Ô»°¡£IanÔÚÁ¬½ÓMongoDBʱ£¬½«×Ô¼ºµÄÓ¦ÓÃÓëÕâ¸ö·þÎñÆ÷ÏàÁ¬¡£µ«²»Í¬ÓÚÖ±½ÓÁ¬½ÓMongDB£¬Ian¿ÉÔÚ²âÊÔʱ°´ÐèÖ¸ÁÈø÷þÎñÆ÷±íÏÖΪÖжϡ¢³¬Ê±µÈ£¬ÒÔ³¹µ×¼ì²âËûȫеĴíÎó´¦ÀíÂß¼¡£
ºÚ¹Ü²âÊÔϵÁаüÀ¨Ïà¹ØÎÄÕºʹúÂ룬ÆäÖÐÌṩÁËÒ»ÇÐËùÐèÄÚÈÝ£¬ÐÖúIan²âÊÔËûÊÇ·ñÕýÈ·ÔËÓÃÁËÕâÏî½â¾ö·½°¸¡£
Ò»¸öÇÉÃîµÄ·½°¸
×îÖÕ£¬ÎÒÃǸøÁËIanÒ»¸ö´ð°¸¡ª¡ªÒ»¸öËû¿ÉÒÔÓÃÔÚ×Ô¼ºÓ¦ÓÃÖеĽâ¾ö·½°¸£¬Ëü¿ÉÒÔÕýÈ·Ó¦¶ÔÔÝÌ¬ÍøÂç´íÎó¡¢å´»úºÍÃüÁî´íÎ󣬶øÇҷdz£ÓÐЧ¡¢Ð§Âʺܸߣ¬Ò²Ô¶±ÈÏëÏóµÄ¼òµ¥¡£ |