×î½ü¿´µ½Ò»ÆªÎÄÕ http://www.anishathalye.com/2017/06/04/testing-distributed-systems-for-linearizability/£¬Ð´µÃ·Ç³£ºÃ£¬ÔÚÕ÷µÃ×÷Õß
Anish ͬÒâµÄÇé¿öÏ£¬¾ö¶¨½«Æä·Òë³ÉÖÐÎÄ¡£µ«ÎªÁ˸üºÃÀí½â£¬Ò»Ð©µØ·½²¢²»»áÖð×Ö·Ò룬Ҳ»áÉÔ×÷µ÷Õû¡£
ÕýȷʵÏÖÒ»¸ö·Ö²¼Ê½ÏµÍ³ÊǷdz£ÓÐÌôÕ½µÄÒ»¼þÊÂÇ飬ÒòΪÐèÒªºÜºÃµÄ´¦Àí²¢·¢ºÍʧ°ÜÕâЩÎÊÌâ¡£ÍøÂç°ü¿ÉÄܱ»ÑÓ³Ù£¬Öظ´£¬ÂÒÐò»òÕß¶ªÆú£¬»úÆ÷¿ÉÄÜÔÚÈκÎʱºòå´»ú¡£¼´Ê¹Ò»Ð©Éè¼Æ±»ÂÛÎÄÖ¤Ã÷ÊÇÕýÈ·µÄ£¬Ò²ÈÔÈ»ºÜÄÑÔÙʵÏÖÖбÜÃâ
bug¡£
³ý·ÇÎÒÃÇʹÓÃÐÎʽ·½·¨[1]£¬²»È»£¬¼´Ê¹ÎÒÃǼÙÉèʵÏÖÊÇÕýÈ·µÄ£¬ÎÒÃÇÒ²ÐèҪȥ²âÊÔϵͳ¡£²âÊÔ·Ö²¼Ê½ÏµÍ³Ò²ÊÇÒ»¼þ·Ç³£ÓÐÌôÕ½µÄÊÂÇé¡£²¢·¢ºÍ²»È·¶¨ÐÔʹµÃÎÒÃÇÔÚ²âÊÔµÄʱºò·Ç³£ÄÑץס
bug£¬ÓÈÆäÊÇÔÚһЩ¼«¶ËÇé¿öÏÂÃæ²Å»á³öÏÖµÄ bug£¬Æ©Èçͬʱ»úÆ÷å´»ú»òÕß¼«¶ËÍøÂçÑÓ³Ù¡£ÕýÈ·ÐÔ
ÔÚÌÖÂÛ²âÊÔ·Ö²¼Ê½ÏµÍ³µÄÕýÈ·ÐÔ֮ǰ£¬ÎÒÃÇÊ×Ïȶ¨ÒåÏÂʲôÊÇ ¡°ÕýÈ·ÐÔ¡±¡£¼´Ê¹¶ÔÓÚһЩ¼òµ¥µÄϵͳ£¬ÒªÍêÈ«µÄÈ·¶¨ÏµÍ³·ûºÏÔ¤ÆÚÒ²ÊÇÒ»¼þÏ൱¸´ÔÓµÄÊÂÇé[2]¡£
¿¼ÂÇÒ»¸ö¼òµ¥µÄ key-value ϵͳ£¬Æ©Èç etcd£¬Ö§³ÖÁ½¸ö²Ù×÷£º
ºÍ
£¬Ê×ÏÈ£¬ÎÒÃÇÐèÒª¿¼ÂÇËüÔÚ˳ÐòÇé¿öÏÂÃæµÄÐÐΪ¡£Ë³Ðò¹æ·¶
ͨ³£¶ÔÓÚÒ»¸ö key-value store£¬ÎÒÃǶÔÓÚËüÔÚ˳Ðò²Ù×÷ÏÂÃæµÄÐÐΪ¶¼ÄÜÓÐÒ»¸öÖ±¹ÛµÄÈÏʶ£º
²Ù×÷Èç¹ûÔÚ
µÄºóÃæ£¬ÄÇôһ¶¨Äܵõ½
µÄ½á¹û¡£Æ©È磬Èç¹û
£¬ÄÇôºóÃæµÄ
¾ÍÄܵõ½
£¬Èç¹ûµÃµ½ÁË
£¬ÄÇôÕâ¾ÍÊDz»¶ÔµÄ¡£
ÎÒÃÇʹÓà Python ¶¨ÒåÒ»¸ö¼òµ¥µÄ key-value store£º
[code]class
KVStore:
def __init__(self):
self._data = {}
def put(self, key, value):
self._data[key] = value
def get(self, key):
return self._data.get(key, "")
[/code]
|
ÉÏÃæµÄ´úÂë±È½Ï¼òµ¥£¬µ«°üº¬ÁË×ã¹»µÄÐÅÏ¢£¬°üÀ¨³õʼ״̬ÊÇÔõÑùµÄ£¬ÄÚ²¿×´Ì¬ÊÇÈçºÎ±»²Ù×÷µÄ½á¹û¸Ä±äµÄ£¬´Ó
key-value store ÀïÃæ²Ù×÷·µ»ØµÄ½á¹ûÊÇÔõÑùµÄ¡£ÕâÀïÐèÒªÁôÒâÏÂ
¶ÔÓÚ²»´æÔÚµÄ key µÄ´¦Àí£¬»á·µ»ØÒ»¸ö empty string¡£ÏßÐÔÒ»ÖÂÐÔ
½ÓÏÂÀ´£¬ÎÒÃÇÀ´¿¼ÂÇÎÒÃÇµÄ key-value store ÔÚ²¢·¢ÏÂÃæ»áÓÐÔõÑùµÄÐÐΪ¡£ÐèҪעÒâ˳Ðò¹æ·¶²¢Ã»ÓÐÖ¸Ã÷ÔÚ²¢·¢²Ù×÷ÏÂÃæ»á·¢Éúʲô¡£Æ©È磬˳Ðò¹æ·¶²¢Ã»ÓÐ˵
key-value store ÔÚÏÂÃæÕâ¸ö³¡¾°Ï¿ÉÒÔÔÊÐíµÄ²Ù×÷¡£

ÎÒÃDz¢²»ÄÜÁ¢¿ÌÖªµÀ
Õâ¸ö²Ù×÷»áÔÊÐí·µ»ØÔõÑùµÄ½á¹û¡£Ö±¾õÉÏ£¬ÎÒÃÇ¿ÉÒÔ˵
ÊǸú
ºÍ
Ò»ÆðÖ´Ðеģ¬ËùÒÔËüÄÜ¿ÉÄÜ·µ»ØÒ»¸öÖµ£¬ÉõÖÁÒ²¿ÉÄÜ·µ»Ø
¡£ Èç¹ûÓÐÁíÒ»¸ö
µÄ²Ù×÷ÔÚ¸üºóÃæÖ´ÐУ¬ÎÒÃÇ¿ÉÒÔ˵Õâ¸öÒ»¶¨ÄÜ·µ»Ø
£¬ÒòΪËüÊÇ×îºóÒ»´ÎдÈëµÄÖµ£¬¶øÇÒÄǸöʱºò²¢Ã»ÓÐÆäËûµÄ²¢·¢Ð´Èë¡£
¶ÔÓÚÒ»¸ö»ùÓÚ˳Ðò¹æ·¶µÄ²¢·¢²Ù×÷À´Ëµ£¬ÎÒÃÇ»áÓÃÒ»¸öÒ»ÖÂÐÔÄ£ÐÍ£¬Ò²¾ÍÊÇÏßÐÔÒ»ÖÂÐÔÀ´ËµÃ÷ËüµÄÕýÈ·ÐÔ¡£ÔÚÒ»¸öÏßÐÔÒ»ÖÂÐÔµÄϵͳÀïÃæ£¬ÈκβÙ×÷¶¼¿ÉÄÜÔÚµ÷ÓûòÕß·µ»ØÖ®¼äÔ×ÓºÍ˲¼äÖ´ÐС£³ýÁËÏßÐÔÒ»ÖÂÐÔ£¬»¹ÓÐһЩÆäËûÒ»ÖÂÐÔµÄÄ£ÐÍ£¬µ«¶àÊý·Ö²¼Ê½ÏµÍ³¶¼ÌṩÁËÏßÐÔÒ»ÖÂÐԵIJÙ×÷£ºÏßÐÔÒ»ÖÂÐÔÊÇÒ»¸öÇ¿µÄÒ»ÖÂÐÔÄ£ÐÍ£¬²¢ÇÒ»ùÓÚÏßÐÔÒ»ÖÂÐÔϵͳ£¬ºÜÈÝÒ×È¥¹¹½¨ÆäËûµÄϵͳ¡£¿¼Âǵ½Èç϶Ô
key-value store ²Ù×÷µÄÀúÊ·Àý×Ó£º

Õâ¸öÀúÊ·ÊÇÒ»¸öÏßÐԵġ£ÔÚÏÂÃæÍ¼Æ¬µÄÀ¶É«µØ·½£¬ÎÒÃÇÏÖʵµÄ±êÃ÷ÁËÏßÐÔÒ»Öµĵ㡣Õâ¸ö˳ÐòÀúÊ·
Put("x",
"0"), Get("x") -> "0",
Put("x", "1"), Get("x")
-> "1" |
£¬¶ÔÓÚ˳Ðò¹æ·¶À´Ëµ¾ÍÊÇÒ»¸öÕýÈ·µÄÀúÊ·¡£

¶ÔÓ¦µÄ£¬ÏÂÃæµÄÀúÊ·¾Í²»ÊÇÏßÐÔÒ»Öµġ£

¶ÔÓÚ˳Ðò¹æ·¶À´Ëµ£¬Õâ¸öÀúÊ·²¢²»ÊÇÏßÐÔÒ»ÖµģºÎÒÃDz¢²»ÄÜÔÚÕâ¸öÀúÊ·µÄ²Ù×÷ÀïÃæÖ¸¶¨³öÏßÐÔÒ»Öµĵ㡣ÎÒÃÇ¿ÉÒÔ»³ö
client 1£¬2 ºÍ 3 µÄ£¬µ«ÎÒÃDz¢²»ÄÜ»³ö client 4 µÄ£¬ÒòΪÕâÃ÷ÏÔÊÇÒ»¸ö¹ýÆÚµÄÖµ¡£ÀàËÆµÄ£¬ÎÒÃÇ¿ÉÒÔ»³ö
client 1£¬2 ºÍ 4 µÄ£¬ÄÇô client 2 µÄ²Ù×÷Ò»¶¨»áÔÚ 4 µÄ²Ù×÷¿ªÊ¼µÄºóÃæ£¬µ«ÕâÑùÎÒÃǾͲ»ÄÜ´¦Àí
client 3£¬ËüÖ»¿ÉÄܺϷ¨µÄ·µ»Ø
""
»òÕß
"0"
¡£²âÊÔ
ÓÐÁËÒ»¸öÕýÈ·ÐԵ͍Ò壬ÎÒÃǾͿÉÒÔ¿¼ÂÇÈçºÎÈ¥²âÊÔ·Ö²¼Ê½ÏµÍ³ÁË¡£Í¨³£µÄ×ö·¨¾ÍÊǶÔÓÚÕýÈ·µÄ²Ù×÷£¬²»Í£µÄ½øÐÐËæ»úµÄ´íÎó×¢È룬ÀàËÆ»úÆ÷å´»ú£¬ÍøÂç¸ôÀëµÈ¡£ÎÒÃÇÉõÖÁÄÜÄ£ÄâÕû¸öÍøÂ磬ÕâÑùÎÒÃǾÍÄÜ×ö³¤Ê±¼äµÄÍøÂçÑӳٵȡ£ÒòΪ²âÊÔÊ±Ëæ»úµÄ£¬ÎÒÃÇÐèÒªÅܺܶà´Î´Ó¶øÈ·¶¨Ò»¸öϵͳµÄʵÏÖÊÇÕýÈ·µÄ¡£×¨ÃŲâÊÔ
ÎÒÃÇʵ¼ÊÈçºÎ×öÕýÈ·²Ù×÷µÄ²âÊÔÄØ£¿ÔÚ×î¼òµ¥µÄÈí¼þÀïÃæ£¬ÎÒÃÇ¿ÉÒÔʹÓÃÊäÈëÊä³ö²âÊÔ£¬Æ©Èç
assert(expected_output
== f(input)) |
£¬ÎÒÃÇÒ²¿ÉÒÔÔÚ·Ö²¼Ê½ÏµÍ³ÉÏÃæÊ¹ÓÃÒ»¸öÀàËÆµÄ·½·¨£¬Æ©È磬¶ÔÓÚ key-value store£¬µ±¶à¸ö
client ¿ªÊ¼Ö´ÐвÙ×÷µÄʱºò£¬ÎÒÃÇ¿ÉÒÔÓÐÈçϵIJâÊÔ£º
[code]for
client_id = 0..10 {
spawn thread {
for i = 0..1000 {
value = rand()
kvstore.put(client_id, value)
assert(kvstore.get(client_id) == value)
}
}
}
wait for threads
[/code] |
Èç¹û²âÊÔ¹ÒµôÁË£¬ÄÇôÕâ¸öϵͳһ¶¨²»ÊÇÏßÐÔÒ»ÖÂÐԵ쬵±È»£¬Õâ¸ö²âÊÔ²¢²»ÊǺÜÍ걸£¬ÒòΪÓпÉÄܲ»ÊÇÏßÐÔÒ»ÖµÄϵͳҲ¿ÉÄÜͨ¹ýÕâ¸ö²âÊÔ¡£ÏßÐÔÒ»ÖÂÐÔ
Ò»¸ö¸üºÃµÄ°ì·¨¾ÍÊDz¢·¢µÄ¿Í»§¶ËÍêÈ«ÅÜËæ»úµÄ²Ù×÷¡£Æ©È磬ѻ·µÄÈ¥µ÷ÓÃ
kvstore.put(rand(),
rand()) |
ºÍ
£¬ÓпÉÄÜ»áÖ»ÓúÜÉÙµÄ key È¥Ôö´ó³åÍ»µÄ¸ÅÂÊ¡£µ«ÔÚÕâÖÖÇé¿öÏ£¬ÎÒÃÇÈçºÎ¶¨ÒåʲôÊÇÕýÈ·µÄ²Ù×÷ÄØ£¿ÔÚÉÏÃæµÄ¼òµ¥µÄ²âÊÔÀïÃæ£¬ÒòΪÿ¸ö
client ¶¼²Ù×÷µÄÊÇÒ»¸ö¶ÀÁ¢µÄ key£¬ËùÒÔÎÒÃÇ¿ÉÒԷdz£Ã÷È·µÄÖªµÀÊä³ö½á¹û¡£
µ«ÊÇ clients ²¢·¢µÄ²Ù×÷ͬһ¶Ñ keys£¬ÊÂÇé¾Í±äµÃ¸´ÔÓÁË¡£ÎÒÃDz¢²»ÄÜԤ֪ÿ¸ö²Ù×÷µÄ·µ»ØÖµÒòΪÕⲢûÑùÒ»¸öΨһµÄ´ð°¸¡£µ«ÎÒÃÇ¿ÉÒÔÓÃÁíÒ»¸ö°ì·¨£ºÎÒÃÇ¿ÉÒԼǼÕû¸ö²Ù×÷µÄÀúÊ·£¬È»ºóÈ¥ÑéÖ¤Õâ¸ö²Ù×÷ÀúÊ·ÊÇÏßÐÔÒ»Öµġ£ÏßÐÔÒ»ÖÂÐÔÑéÖ¤
Ò»¸öÏßÐÔÒ»ÖÂÐÔÑéÖ¤Æ÷»áʹÓÃÒ»¸ö˳Ðò¹æ·¶ºÍÒ»¸ö²¢·¢²Ù×÷µÄÀúÊ·£¬È»ºóÖ´ÐÐÒ»¸öÅж¨³ÌÐòÈ¥¼ì²éÕâ¸öÀúÊ·Ôڹ淶ÏÂÃæÊÇ·ñÏßÐÔÒ»Ö¡£NP
Í걸
µ«²»ÐÒµÄÊÇ£¬ÏßÐÔÒ»ÖÂÐÔÑéÖ¤ÊÇ NP Í걸µÄ¡£Õâ¸öÖ¤Ã÷·Ç³£¼òµ¥£ºÎÒÃÇÄÜ˵Ã÷ÏßÐÔÒ»ÖÂÐÔÑéÖ¤ÊÇ NP ÎÊÌ⣬²¢ÇÒÒ²ÄÜչʾһ¸ö
NP À§ÄÑÎÊÌâÄܱ»¼ò»¯³ÉÏßÐÔÒ»ÖÂÐÔÑéÖ¤¡£Ã÷ÏԵģ¬ÏßÐÔÒ»ÖÂÐÔÑéÖ¤ÊÇ NP ÎÊÌ⣬ƩÈ磬ËùÓвÙ×÷µÄÏßÐÔÒ»ÖÂÐԵ㣬¸ù¾ÝÏà¹ØµÄ˳Ðò¹æ·¶£¬ÎÒÃÇ¿ÉÒÔÔÚ¶àÏîʽʱ¼äÀïÑéÖ¤¡£
ΪÁË˵Ã÷ÏßÐÔÒ»ÖÂÐÔÑéÖ¤ÊÇ NP À§Äѵģ¬ÎÒÃÇ¿ÉÒÔ½«×Ó¼¯ºÏÎÊÌâ¼ò»¯³ÉÏßÐÔÒ»ÖÂÐÔÑéÖ¤¡£¶ÔÓÚ×Ó¼¯ºÏÎÊÌ⣬ÎÒÃǸø³ö·Ç¸ºÊýµÄ¼¯ºÏ
ºÍÄ¿±ê½á¹û t£¬È»ºóÎÒÃDZØÐëÈ·¶¨ÊÇ·ñ´æÔÚÒ»¸ö×Ó¼¯ S µÄºÏµÈÓÚ t¡£ÎÒÃÇ¿ÉÒÔ½«Õâ¸öÎÊÌâ¼ò»¯³ÉÈçϵÄÏßÐÔÒ»ÖÂÐÔÑéÖ¤¡£¿¼ÂÇ˳Ðò¹æ·¶£º
[code]class
Adder:
def __init__(self):
self._total = 0
def add(self, value):
self._total += value
def get(self):
return self._total |
ÒÔ¼°ÀúÊ·£º

Ö»ÓÐÔÚ×Ó¼¯ºÏÎÊÌâµÄ´ð°¸ÊÇ ¡°yes¡± µÄʱºò£¬ÀúÊ·²ÅÊÇÏßÐԵġ£Èç¹ûÀúÊ·ÊÇÏßÐԵģ¬ÄÇôÎÒÃÇÈÏΪ¶ÔÓÚÈκεÄ
²Ù×÷£¬ÔÚ
²Ù×÷֮ǰ¶¼ÓÐÏßÐÔÒ»ÖÂÐԵ㣬Õâ¸ö¾Í¶ÔÓ¦ÁËÔÚ×Ó¼¯ÀïÃæ
£¬ËüµÄºÏÊÇ t¡£Èç¹ûÕâ¸ö¼¯ºÏÀïÃæÓÐÒ»¸ö×Ó¼¯µÄºÏÊÇ t£¬ÎÒÃǾÍÄܹ¹ÔìÒ»¸öÏßÐÔ»¯£¬ËüÓÐÔÚ
²Ù×÷·¢Éú֮ǰ£¬¶ÔÓ¦×Ó¼¯
µÄ
µÄ²Ù×÷£¬Ò²ÓÐÔÚ
²Ù×÷Ö®ºóÆäÓàµÄ²Ù×÷¡£
PS£ºÕâ¸öÕ½ÚÎÒ´ó¸ÅÖªµÀɶÒâ˼£¬µ«Ã»ÕÒµ½¸üºÃµÄ±íÊöÀ´·Ò룬Ҳ¾Í´ÕºÏ×ÅÁË¡£ºóÃæÔÙ¿´ paper À´ÉîÈëÁ˽â°É¡£ÊµÏÖ
¼´Ê¹ÏßÐÔÒ»ÖÂÐÔÑéÖ¤ÊÇ NP ÍêÈ«µÄ£¬ÔÚʵ¼ÊÖУ¬ËüÈÔÈ»ÄÜÔÚһЩСµÄÀúÊ·ÉÏÃæºÜºÃµÄ¹¤×÷¡£ÏßÐÔÒ»ÖÂÐÔÑéÖ¤Æ÷µÄʵÏÖ»áÓÃÒ»¸ö¿ÉÖ´ÐеĹ淶£¬¼ÓÉÏÒ»¸öÀúÊ·£¬Ö´ÐÐÒ»¸öËÑË÷¹ý³ÌÈ¥¹¹ÔìÒ»¸öÏßÐÔ»¯£¬²¢Ê¹ÓÃһЩ¼¼ÇÉÀ´ÏÞÖÆ¼õÉÙËÑË÷µÄ¿Õ¼ä¡£
ÔÚ Jepsen ÀïÃæ£¬ÓÐÒ»¸öÒ»ÖÂÐÔÑéÖ¤¹¤¾ß Knossos£¬µ«²»ÐÒµÄÊÇ£¬ÔÚ²âÊÔһЩ·Ö²¼Ê½ key-value
store µÄʱºò£¬Knossos ²¢²»ÄܺܺõŤ×÷£¬Ëü¿ÉÄÜÖ»ÄÜÊÊÓÃÓÚһЩÉٵIJ¢·¢ clients£¬ÒÔ¼°Ö»Óм¸°ÙµÄʼþµÄÀúÊ·¡£µ«ÔÚһЩ²âÊÔÀïÃæ£¬ÓкܶàµÄ
clients£¬ÒÔ¼°»áÉú³É¸ü¶àµÄÀúʷʼþ¡£ÎªÁ˽â¾ö Knossos µÄÎÊÌ⣬×÷Õß¿ª·¢ÁË Procupine£¬Ò»¸öÓÃ
Go дµÄ¸ü¿ìµÄÏßÐÔÒ»ÖÂÐÔÑéÖ¤¹¤¾ß¡£Porcupine ʹÓÃÒ»¸öÓà Go ¿ª·¢µÄÖ´Ðй淶ȥÑéÖ¤ÀúÊ·ÊÇ·ñÊÇÏßÐԵġ£¸ù¾Ýʵ¼Ê²âÊÔµÄÇé¿ö£¬Porcupine
±È Knossos ¿ìºÜ¶à±¶¡£Ð§¹û
ÔÚ²âÊÔ·Ö²¼Ê½ÏµÍ³µÄÏßÐÔÒ»ÖÂÐÔµÄʱºò£¬Ê¹ÓôíÎó×¢ÈëÊÇÒ»¸öºÜÓÐЧµÄÊֶΡ£
×÷Ϊ¶Ô±È£¬ÔÚʹÓÃרÃŵIJâÊÔÓà Porcupine ²âÊÔ key-value store µÄʱºò£¬×÷ÕßʹÓÃÁËÕâÁ½ÖÖ·½Ê½¡£×÷ÕßÔÚʵÏÖËü×Ô¼ºµÄ
key-value store µÄʱºòÒýÈ벻ͬµÄÉè¼Æ´íÎ󣬯©ÈçÔÚÐÞ¸ÄÖ®ºó»á³öÏÖ¹ýÆÚ¶Á£¬À´¿´ÕâЩ²âÊÔÊÇ·ñ»á¹Òµô¡£×¨ÃŲâÊԻᲶ׽µ½ºÜ¶à
bugs£¬µ«²¢Ã»ÓÐÄÜÁ¦È¥²¶×½µ½¸ü¶àµÄ½Æ»«µÄ bugs¡£Ïà¶Ô¶øÑÔ£¬×÷ÕßÏÖÔÚ»¹Ã»ÕÒµ½Ò»¸öÕýÈ·Ð﵀ bug
ÊÇÏßÐÔÒ»ÖÂÐÔ²âÊÔ²»ÄÜץסµÄ¡£
ÐÎʽ·½·¨Äܹ»±£Ö¤Ò»¸ö·Ö²¼Ê½ÏµÍ³µÄÕýÈ·ÐÔ¡£ÀýÈ磬UM PLSE Ñо¿Ð¡×é×î½üʹÓà Coq proof
assistnt À´ÑéÖ¤ÁË Raft Ò»ÖÂÐÔÐÒé¡£µ«²»ÐҵĵÄÊÇ£¬ÑéÖ¤ÐèÒªÌØ¶¨µÄ֪ʶ£¬ÁíÍâÑé֤ʵ¼ÊµÄϵͳÐèÒª×ö´óÁ¿µÄ¹¤×÷¡£Ã»×¼ÓÐÒ»Ì죬ÑéÖ¤Äܱ»ÓÃÔÚʵ¼ÊϵͳÉÏÃæ£¬µ«ÏÖÔÚ£¬Ö÷Òª»¹ÊDzâÊÔ£¬¶ø²»ÊÇÑéÖ¤¡£
ÀíÂÛÉÏ£¬ËùÓеÄÉú²úϵͳ¶¼»áÓÐÒ»¸öÐÎʽ¹æ·¶£¬¶øÇÒһЩϵͳҲÒѾÓÐÁË£¬Æ©Èç Raft ¾ÍÓÐÒ»¸öÓà TLA+
дµÄÐÎʽ¹æ·¶¡£µ«²»ÐÒµÄÊÇ£¬´ó²¿·ÖµÄϵͳÊÇûÓеġ£ |