การโต้แย้งข้อมูล NDB แย่ลงเรื่อยๆ

ฉันมีปัญหาแปลกๆนิดหน่อย ฉันมีโมดูลที่ทำงานบน gae ที่วางงานเล็กๆ น้อยๆ มากมายไว้ในคิวงานเริ่มต้น งานเข้าถึงโมดูล ndb เดียวกัน แต่ละงานเข้าถึงข้อมูลจำนวนมากจากตารางที่แตกต่างกันสองสามตาราง จากนั้นจึงเรียก put

งานสองสามงานแรกทำงานได้ดี แต่เมื่อเวลาผ่านไป ฉันเริ่มได้งานเหล่านี้ในช่วงสุดท้าย put:

suspended generator _put_tasklet(context.py:358) raised TransactionFailedError(too much contention on these datastore entities. please try again.)

ดังนั้นฉันจึงลองใส่ชุด Put และใส่ระยะหมดเวลาแบบสุ่ม เพื่อให้ลองใหม่สองสามครั้ง สิ่งนี้ช่วยบรรเทาปัญหาได้เล็กน้อย แต่จะเกิดขึ้นในภายหลัง

นี่คือรหัสเทียมสำหรับงานของฉัน:

def my_task(request):
    stuff = get_ndb_instances() #this accessed a few things from different tables
    better_stuff = process(ndb_instances) #pretty much just a summation
    try_put(better_stuff)
    return {'status':'Groovy'}

def try_put(oInstance,iCountdown=10):
    if iCountdown<1:
        return oInstance.put()
    try:
        return oInstance.put()
    except:
        import time
        import random 
        logger.info("sleeping")
        time.sleep(random.random()*20)
        return oInstance.try_put(iCountdown-1)

หากไม่ใช้ try_put คิวจะผ่านไปได้ประมาณ 30% จนกว่าจะหยุดทำงาน ด้วย try_put มันจะเพิ่มขึ้นอีก เช่น 60%

เป็นไปได้ไหมว่างานยังคงเชื่อมต่อกับการเชื่อมต่อ ndb หลังจากเสร็จสิ้นแล้ว? ฉันไม่ได้ใช้ธุรกรรมอย่างชัดเจน

แก้ไข:

ดูเหมือนว่าจะมีความสับสนเกี่ยวกับสิ่งที่ฉันถาม คำถามคือ: เหตุใดการโต้แย้ง ndb จึงแย่ลงเมื่อเวลาผ่านไป ฉันมีงานจำนวนมากที่ทำงานพร้อมกัน และพวกเขาเข้าถึง ndb ในลักษณะที่อาจทำให้เกิดความขัดแย้งได้ หากตรวจพบข้อขัดแย้ง การลองซ้ำตามกำหนดเวลาแบบสุ่มจะเกิดขึ้น และสิ่งนี้จะกำจัดข้อโต้แย้งได้อย่างสมบูรณ์ สักพักหนึ่ง. งานยังคงดำเนินต่อไปและเสร็จสิ้น และยิ่งส่งคืนได้สำเร็จมากเท่าใด การโต้แย้งก็จะเกิดขึ้นมากขึ้นเท่านั้น แม้ว่ากระบวนการที่ใช้ข้อมูลที่โต้แย้งควรเสร็จสิ้นแล้ว มีบางอย่างเกิดขึ้นที่จับที่ datastore ซึ่งไม่ควรเป็นเช่นนั้นหรือไม่? เกิดอะไรขึ้น?

แก้ไข 2:

ต่อไปนี้เป็นข้อมูลเล็กน้อยเกี่ยวกับโครงสร้างสำคัญในการเล่น:

โมเดล ndb ของฉันอยู่ในลำดับชั้นที่เรามีสิ่งนี้ (ทิศทางของลูกศรระบุความสัมพันธ์ระหว่างผู้ปกครองและเด็ก เช่น: Type มีอินสแตนซ์ย่อยจำนวนมาก เป็นต้น)

Type->Instance->Position

รหัสของตำแหน่งถูกจำกัดให้ใช้ชื่อที่แตกต่างกันสองสามชื่อ มีหลายพันอินสแตนซ์และมีไม่หลายประเภท

ฉันคำนวณตำแหน่งต่างๆ แล้วลอง try_put_multi (คล้ายกับ try_put ในลักษณะที่ชัดเจน) และเกิดความขัดแย้ง ฉันจะเรียกใช้โค้ดอีกครั้งในเร็วๆ นี้ และรับการติดตามย้อนกลับแบบเต็มเพื่อรวมไว้ที่นี่


comment
คุณแทบไม่ได้ลอง/ยกเว้นเลยจริงๆ เหรอ?   -  person Tim Hoffman    schedule 16.02.2016
comment
โครงสร้างหลักที่ใช้คืออะไร คุณได้รับข้อผิดพลาดในการโต้แย้งประเภทใด   -  person Tim Hoffman    schedule 16.02.2016
comment
@TimHoffman: ไม่ รหัสนี้เป็นเวอร์ชันย่อของของจริง   -  person Sheena    schedule 01.03.2016
comment
@TimHoffman: เป็นการโต้แย้งประเภทใหม่ ฉันไม่ได้รับข้อมูลมากนักนอกเหนือจากข้อยกเว้นที่ฉันวางไว้ในคำถามด้านบน ฉันจะแก้ไขเพื่อพูดคุยเกี่ยวกับโครงสร้างที่สำคัญ   -  person Sheena    schedule 01.03.2016
comment
@BrentWashburne: ฉันไม่เชื่อว่านี่จะซ้ำกัน ปัญหาก็คือความขัดแย้งจะแย่ลงเรื่อยๆ เมื่อเวลาผ่านไป แม้ว่าจำนวนกระบวนการที่เกี่ยวข้องกับข้อมูลจะมีขีดจำกัดสูงสุดก็ตาม   -  person Sheena    schedule 01.03.2016
comment
คุณเห็นว่าจำนวนอินสแตนซ์ของแอปเพิ่มขึ้นในช่วงเวลานี้โดยบังเอิญหรือไม่?   -  person Dan Cornilescu    schedule 01.03.2016
comment
@DanCornilescu: ฉันจะเรียกใช้สิ่งนี้อีกครั้งและรับตัวเลขเหล่านั้น   -  person Sheena    schedule 01.03.2016
comment
Instances นับพันถึงไม่กี่ Types =› กลุ่มเอนทิตีขนาดใหญ่ แต่ละกลุ่มรองรับการเขียนสูงสุด ~ 1 รายการต่อวินาที อัตราของงานในการอัปเดต Instances สำหรับ Type พาเรนต์เดียวกัน (เช่น กลุ่มเดียวกัน) เป็นเท่าใด คุณมี threadsafe: true ในการกำหนดค่า .yaml ของคุณหรือไม่   -  person Dan Cornilescu    schedule 01.03.2016


คำตอบ (1)


การโต้แย้งจะเลวร้ายลงหากคุณมีการเขียน/ธุรกรรมเกิน 1 ครั้งต่อกลุ่มเอนทิตีต่อวินาทีอย่างต่อเนื่อง คำตอบอยู่ที่วิธีการทำงานของ Megastore/Paxo และวิธีที่ Cloud Datastore จัดการกับความขัดแย้งในแบ็กเอนด์

เมื่อมีการพยายามเขียน 2 ครั้งพร้อมกันบนโหนดที่แตกต่างกันใน Megastore ธุรกรรมหนึ่งจะชนะและอีกรายการหนึ่งจะล้มเหลว Cloud Datastore ตรวจพบข้อโต้แย้งนี้และจะลองทำธุรกรรมที่ล้มเหลวอีกครั้งหลายครั้ง โดยปกติแล้วสิ่งนี้จะส่งผลให้ธุรกรรมประสบความสำเร็จโดยไม่มีข้อผิดพลาดใด ๆ เกิดขึ้นกับลูกค้า

หากมีการพยายามเขียนอย่างต่อเนื่องเกินขีดจำกัดที่แนะนำ โอกาสที่ธุรกรรมจะต้องลองใหม่หลายครั้งจะเพิ่มขึ้น จำนวนธุรกรรมในสถานะการลองใหม่ภายในยังเพิ่มขึ้น ในที่สุด ธุรกรรมจะเริ่มถึงขีดจำกัดการลองใหม่ภายในของเรา และจะส่งข้อผิดพลาดการโต้แย้งกลับไปยังลูกค้า

วิธีการนอนหลับแบบสุ่มเป็นวิธีที่ไม่ถูกต้องในการจัดการกับสถานการณ์การตอบสนองข้อผิดพลาด คุณควรพิจารณาการถอยกลับแบบทวีคูณด้วยความกระวนกระวายใจแทน (ตัวอย่าง)

ในทำนองเดียวกัน แก่นของปัญหาของคุณคืออัตราการเขียนที่สูงในกลุ่มเอนทิตีเดียว คุณควรพิจารณาว่าจำเป็นต้องมีการเลี้ยงดูอย่างชัดเจนหรือไม่ (หากไม่ลบออก) หรือคุณควรแยกกลุ่มเอนทิตีในลักษณะที่เหมาะสมตามคำค้นหาและข้อกำหนดด้านความสอดคล้องของคุณ

person Dan McGrath    schedule 28.12.2016