Redis ஐப் பயன்படுத்தி பூட்டுதல் விநியோகிக்கப்பட்டது

ஹே ஹப்ர்!

Redis ஐப் பயன்படுத்தி விநியோகிக்கப்பட்ட பூட்டுதலை செயல்படுத்துவது பற்றிய சிக்கலான கட்டுரையின் மொழிபெயர்ப்பை இன்று உங்கள் கவனத்திற்குக் கொண்டு வருகிறோம், மேலும் Redis இன் வாய்ப்புகளைப் பற்றி ஒரு தலைப்பாகப் பேச உங்களை அழைக்கிறோம். புத்தகத்தின் ஆசிரியரான மார்ட்டின் க்ளெப்மேனிடமிருந்து கேள்விக்குரிய ரெட்லாக் அல்காரிதம் பற்றிய பகுப்பாய்வு "அதிக சுமை பயன்பாடுகள்", வழங்கப்பட்டது இங்கே.

விநியோகிக்கப்பட்ட பூட்டுதல் என்பது பல சூழல்களில் பயன்படுத்தப்படும் மிகவும் பயனுள்ள பழமையானது, அங்கு பல்வேறு செயல்முறைகள் பகிரப்பட்ட வளங்களில் பரஸ்பர பிரத்தியேகமான முறையில் செயல்பட வேண்டும்.

Redis ஐப் பயன்படுத்தி DLM (விநியோகிக்கப்பட்ட பூட்டு மேலாளர்) எவ்வாறு செயல்படுத்துவது என்பதை விவரிக்கும் பல நூலகங்கள் மற்றும் இடுகைகள் உள்ளன, ஆனால் ஒவ்வொரு நூலகமும் வெவ்வேறு அணுகுமுறையைப் பயன்படுத்துகின்றன, மேலும் அவை வழங்கும் உத்தரவாதங்கள் சற்று அதிநவீன வடிவமைப்புடன் ஒப்பிடும்போது மிகவும் பலவீனமாக உள்ளன.

இந்தக் கட்டுரையில், Redis ஐப் பயன்படுத்தி விநியோகிக்கப்பட்ட பூட்டுதலை எவ்வாறு செயல்படுத்துவது என்பதை நிரூபிக்கும் நிபந்தனைக்குட்பட்ட நியமன வழிமுறையை விவரிக்க முயற்சிப்போம். என்ற அல்காரிதம் பற்றி பேசுவோம் ரெட்லாக், இது ஒரு விநியோகிக்கப்பட்ட பூட்டு மேலாளரை செயல்படுத்துகிறது மற்றும் எங்கள் கருத்துப்படி, இந்த அல்காரிதம் வழக்கமான ஒற்றை நிகழ்வு அணுகுமுறையை விட பாதுகாப்பானது. சமூகம் அதை ஆய்வு செய்து, கருத்துக்களை வழங்கும், மேலும் சிக்கலான அல்லது மாற்று திட்டங்களுக்கான தொடக்கப் புள்ளியாக அதைப் பயன்படுத்தும் என்று நம்புகிறோம்.

அமலாக்கங்கள்

அல்காரிதத்தின் விளக்கத்திற்குச் செல்வதற்கு முன், ஆயத்த செயலாக்கங்களுக்கான பல இணைப்புகளை நாங்கள் வழங்குகிறோம். அவை குறிப்புக்காகப் பயன்படுத்தப்படலாம்.

  • Redlock-rb (ரூபிக்கு செயல்படுத்துதல்). கூட உள்ளது முள் கரண்டி Redlock-rb, இது விநியோகத்தின் எளிமைக்காக ஒரு தொகுப்பை (மாணிக்கம்) சேர்க்கிறது, அது மட்டுமல்ல.
  • Redlock-py (பைத்தான் செயல்படுத்தல்).
  • காற்றோட்டம் (Asyncio Python க்கான செயல்படுத்தல்).
  • Redlock-php (PHP க்கான செயல்படுத்தல்).
  • PHPRedisMutex (PHPக்கான மற்றொரு செயலாக்கம்)
  • cheprasov/php-redis-lock (பூட்டுகளுக்கான PHP நூலகம்)
  • Redsync (கோவிற்கு செயல்படுத்துதல்).
  • ரெடிசன் (ஜாவாவுக்கான செயலாக்கம்).
  • ரெடிஸ்::DistLock (Perl க்கான செயல்படுத்தல்).
  • Redlock-cpp (C++ க்கான செயல்படுத்தல்).
  • Redlock-cs (C#/.NET க்கான செயல்படுத்தல்).
  • RedLock.net (C#/.NET க்கான செயல்படுத்தல்). ஒத்திசைவு மற்றும் பூட்டு நீட்டிப்புகளுக்கான ஆதரவுடன்.
  • ஸ்கார்லெட்லாக் (கட்டமைக்கக்கூடிய தரவு சேமிப்புடன் C# .NET க்கான செயல்படுத்தல்)
  • Redlock4Net (C# .NET க்கான செயல்படுத்தல்)
  • முனை-ரெட்லாக் (NodeJS க்கான செயல்படுத்தல்). பூட்டுகளை நீட்டிப்பதற்கான ஆதரவை உள்ளடக்கியது.

பாதுகாப்பு மற்றும் கிடைக்கும் உத்தரவாதங்கள்

விநியோகிக்கப்பட்ட பூட்டுதலைத் திறம்படப் பயன்படுத்துவதற்குத் தேவையான குறைந்தபட்ச உத்தரவாதங்களை வழங்குவதாக நாங்கள் நினைக்கும் மூன்று பண்புகளுடன் எங்கள் வடிவமைப்பை மாதிரியாக்கப் போகிறோம்.

  1. பாதுகாப்பு சொத்து: பரஸ்பர விலக்கு. எந்த நேரத்திலும், ஒரு வாடிக்கையாளர் மட்டுமே பூட்டை வைத்திருக்க முடியும்.
  2. கிடைக்கும் சொத்து A: முட்டுக்கட்டைகள் இல்லை. வளத்தைப் பூட்டிய கிளையன்ட் தோல்வியடைந்தாலும் அல்லது வேறு வட்டுப் பிரிவில் இறங்கினாலும், இறுதியில் பூட்டைப் பெறுவது எப்போதும் சாத்தியமாகும்.
  3. கிடைக்கும் சொத்து B: தவறு சகிப்புத்தன்மை. பெரும்பான்மையான ரெடிஸ் நோட்கள் இயங்கும் வரை, வாடிக்கையாளர்கள் பூட்டுகளைப் பெற்று வெளியிட முடியும்.

தோல்வி மீட்பு அடிப்படையில் செயல்படுத்துவது ஏன் இந்த விஷயத்தில் போதாது
நாம் எதை மேம்படுத்தப் போகிறோம் என்பதைப் புரிந்து கொள்ள, ரெடிஸ் அடிப்படையிலான பெரும்பாலான விநியோகிக்கப்பட்ட பூட்டு நூலகங்களின் தற்போதைய விவகாரங்களை பகுப்பாய்வு செய்வோம்.

ரெடிஸைப் பயன்படுத்தி ஒரு ஆதாரத்தைப் பூட்டுவதற்கான எளிய வழி, நிகழ்வில் ஒரு விசையை உருவாக்குவதாகும். பொதுவாக, ஒரு விசை வரையறுக்கப்பட்ட வாழ்நாளில் உருவாக்கப்பட்டது, இது Redis இல் வழங்கப்பட்ட காலாவதியாகும் அம்சத்தைப் பயன்படுத்தி அடையப்படுகிறது, எனவே விரைவில் அல்லது பின்னர் இந்த விசை வெளியிடப்படும் (எங்கள் பட்டியலில் உள்ள சொத்து 2). கிளையன்ட் ஆதாரத்தை வெளியிட வேண்டியிருக்கும் போது, ​​​​அது விசையை நீக்குகிறது.

முதல் பார்வையில், இந்த தீர்வு நன்றாக வேலை செய்கிறது, ஆனால் ஒரு சிக்கல் உள்ளது: எங்கள் கட்டிடக்கலை தோல்வியின் ஒரு புள்ளியை உருவாக்குகிறது. ஹோஸ்ட் ரெடிஸ் நிகழ்வு தோல்வியடைந்தால் என்ன நடக்கும்? அப்படியானால் ஒரு அடிமையைச் சேர்ப்போம்! வழங்குபவர் கிடைக்கவில்லை என்றால் நாங்கள் அதைப் பயன்படுத்துவோம். துரதிர்ஷ்டவசமாக, இந்த விருப்பம் சாத்தியமில்லை. இதைச் செய்வதன் மூலம், பாதுகாப்பை உறுதி செய்ய வேண்டிய பரஸ்பர விலக்கு சொத்தை எங்களால் சரியாகச் செயல்படுத்த முடியாது, ஏனெனில் ரெடிஸில் பிரதி எடுப்பது ஒத்திசைவற்றது.

வெளிப்படையாக, அத்தகைய மாதிரியில் ஒரு இனம் நிலை ஏற்படுகிறது:

  1. கிளையண்ட் A மாஸ்டரின் பூட்டைப் பெறுகிறது.
  2. முக்கிய நுழைவு அடிமைக்கு மாற்றப்படுவதற்கு முன்பு மாஸ்டர் தோல்வியடைகிறார்.
  3. பின்பற்றுபவர் தலைவராக பதவி உயர்வு பெறுகிறார்.
  4. A ஏற்கனவே பூட்டிய அதே ஆதாரத்தின் மீது கிளையண்ட் B ஒரு பூட்டைப் பெறுகிறது. பாதுகாப்பு மீறல்!

சில நேரங்களில் அது ஒரு தோல்வி போன்ற சிறப்பு சூழ்நிலைகளில், பல வாடிக்கையாளர்கள் ஒரே நேரத்தில் பூட்டை வைத்திருக்க முடியும் என்பது முற்றிலும் இயல்பானது. இதுபோன்ற சந்தர்ப்பங்களில், பிரதி அடிப்படையிலான தீர்வு பயன்படுத்தப்படலாம். இல்லையெனில், இந்த கட்டுரையில் விவரிக்கப்பட்டுள்ள தீர்வை நாங்கள் பரிந்துரைக்கிறோம்.

ஒரே நிகழ்வில் சரியான செயல்படுத்தல்

மேலே விவரிக்கப்பட்ட ஒற்றை-நிகழ்வு உள்ளமைவின் குறைபாடுகளை சமாளிக்க முயற்சிக்கும் முன், இந்த எளிய வழக்கை எவ்வாறு சரியாகக் கையாள்வது என்பதைப் புரிந்துகொள்வோம், ஏனெனில் இந்த தீர்வு உண்மையில் ஒரு பந்தய நிலைமையை அவ்வப்போது ஏற்றுக்கொள்ளக்கூடிய பயன்பாடுகளில் செல்லுபடியாகும், மேலும் தடை செய்வதால் இங்கே விவரிக்கப்பட்டுள்ள விநியோகிக்கப்பட்ட அல்காரிதத்தில் பயன்படுத்தப்படும் அடிப்படையாக ஒற்றை நிகழ்வு செயல்படுகிறது.

பூட்டைப் பெற, இதைச் செய்யுங்கள்:

SET resource_name my_random_value NX PX 30000

30000 மில்லி விநாடிகள் (PX விருப்பம்) செல்லுபடியாகும் காலத்துடன் (NX விருப்பம்) ஏற்கனவே இல்லை என்றால் மட்டுமே இந்தக் கட்டளை ஒரு விசையை நிறுவுகிறது. திறவுகோல் "myrandomvalue" இந்த மதிப்பு அனைத்து கிளையண்டுகள் மற்றும் அனைத்து பூட்டு கோரிக்கைகளிலும் தனிப்பட்டதாக இருக்க வேண்டும்.
அடிப்படையில், ஒரு சீரற்ற மதிப்பானது, பூட்டைப் பாதுகாப்பாக வெளியிடப் பயன்படுகிறது, ஸ்கிரிப்ட் ரெடிஸிடம் கூறுகிறது: விசை இருந்தால் மட்டுமே அதை அகற்றவும், அதில் சேமிக்கப்பட்ட மதிப்பு எதிர்பார்த்ததுதான். பின்வரும் லுவா ஸ்கிரிப்டைப் பயன்படுத்தி இது அடையப்படுகிறது:

if redis.call("get",KEYS[1]) == ARGV[1] then
    return redis.call("del",KEYS[1])
else
    return 0
end

மற்றொரு கிளையன்ட் வைத்திருக்கும் பூட்டை அகற்றுவதைத் தடுக்க இது முக்கியம். எடுத்துக்காட்டாக, ஒரு கிளையன்ட் ஒரு பூட்டைப் பெறலாம், பின்னர் முதல் பூட்டை விட நீண்ட நேரம் நீடிக்கும் சில செயல்பாட்டில் பூட்டப்படலாம் (அதனால் சாவி காலாவதியாகும் நேரம் இருக்கும்), பின்னர் வேறு சில கிளையன்ட் வைத்த பூட்டை அகற்றவும்.
ஒரு எளிய DEL ஐப் பயன்படுத்துவது பாதுகாப்பற்றது, ஏனெனில் ஒரு கிளையன்ட் மற்றொரு கிளையண்ட் வைத்திருக்கும் பூட்டை அகற்ற முடியும். மாறாக, மேலே உள்ள ஸ்கிரிப்டைப் பயன்படுத்தும் போது, ​​ஒவ்வொரு பூட்டும் ஒரு சீரற்ற சரத்துடன் "கையொப்பமிடப்பட்டுள்ளது", எனவே முன்பு அதை வைத்த கிளையன்ட் மட்டுமே அதை அகற்ற முடியும்.

இந்த சீரற்ற சரம் என்னவாக இருக்க வேண்டும்? /dev/urandom இலிருந்து 20 பைட்டுகள் இருக்க வேண்டும் என்று நான் யூகிக்கிறேன், ஆனால் உங்கள் நோக்கங்களுக்காக சரத்தை தனித்துவமாக்க குறைந்த விலை வழிகளைக் காணலாம். எடுத்துக்காட்டாக, RC4 ஐ /dev/urandom உடன் விதைத்து, அதிலிருந்து ஒரு போலி சீரற்ற ஸ்ட்ரீமை உருவாக்குவது நன்றாக இருக்கும். ஒரு எளிய தீர்வு மைக்ரோ செகண்ட் தெளிவுத்திறனில் யூனிக்ஸ் நேரம் மற்றும் கிளையன்ட் ஐடி ஆகியவற்றின் கலவையை உள்ளடக்கியது; இது அவ்வளவு பாதுகாப்பானது அல்ல, ஆனால் பெரும்பாலான சூழல்களில் இது பணியைப் பொறுத்தது.

விசையின் வாழ்நாளின் அளவீடாக நாம் பயன்படுத்தும் நேரம் "பூட்டு வாழ்நாள்" எனப்படும். இந்த மதிப்பு என்பது பூட்டு தானாக வெளியிடப்படுவதற்கு முன் எவ்வளவு நேரம் ஆகும் என்பதும், பரஸ்பர விலக்கு உத்தரவாதங்களை மீறாமல், மற்றொரு கிளையன்ட் அந்த வளத்தை பூட்டுவதற்கு முன்பு ஒரு கிளையன்ட் செயல்பாட்டை முடிக்க வேண்டிய நேரம் ஆகும். இந்த உத்தரவாதம் ஒரு குறிப்பிட்ட நேர சாளரத்திற்கு மட்டுமே வரையறுக்கப்பட்டுள்ளது, இது பூட்டு வாங்கிய தருணத்திலிருந்து தொடங்குகிறது.

எனவே ஒரு பூட்டைப் பெறுவதற்கும் வெளியிடுவதற்கும் ஒரு நல்ல வழியைப் பற்றி நாங்கள் விவாதித்தோம். கணினி (ஒரே மற்றும் எப்போதும் கிடைக்கும் நிகழ்வைக் கொண்ட விநியோகிக்கப்படாத அமைப்பைப் பற்றி நாம் பேசினால்) பாதுகாப்பானது. இந்த கருத்தை விநியோகிக்கப்பட்ட அமைப்பிற்கு விரிவுபடுத்துவோம், அங்கு அத்தகைய உத்தரவாதங்கள் இல்லை.

ரெட்லாக் அல்காரிதம்

அல்காரிதத்தின் விநியோகிக்கப்பட்ட பதிப்பு எங்களிடம் N ரெடிஸ் மாஸ்டர்கள் இருப்பதாகக் கருதுகிறது. இந்த முனைகள் ஒன்றுக்கொன்று முற்றிலும் சார்பற்றவை, எனவே நாங்கள் பிரதி அல்லது வேறு எந்த மறைமுகமான ஒருங்கிணைப்பு அமைப்பையும் பயன்படுத்த மாட்டோம். ஒரே நிகழ்வில் பூட்டைப் பாதுகாப்பாகப் பெறுவது மற்றும் விடுவிப்பது எப்படி என்பதை நாங்கள் ஏற்கனவே கூறியுள்ளோம். அல்காரிதம், ஒரு நிகழ்வில் வேலை செய்யும் போது, ​​சரியாக இந்த முறையைப் பயன்படுத்தும் என்பதை நாங்கள் எடுத்துக்கொள்கிறோம். எங்கள் எடுத்துக்காட்டுகளில், N ஐ 5 ஆக அமைக்கிறோம், இது ஒரு நியாயமான மதிப்பாகும். எனவே, வெவ்வேறு கணினிகள் அல்லது மெய்நிகர் கணினிகளில் 5 ரெடிஸ் மாஸ்டர்களைப் பயன்படுத்த வேண்டும், அவை ஒருவருக்கொருவர் பெரும்பாலும் சுயாதீனமாக செயல்படுகின்றன.

பூட்டைப் பெற, வாடிக்கையாளர் பின்வரும் செயல்பாடுகளைச் செய்கிறார்:

  1. தற்போதைய நேரத்தை மில்லி விநாடிகளில் பெறுகிறது.
  2. எல்லா நிகழ்வுகளிலும் ஒரே முக்கிய பெயர் மற்றும் சீரற்ற மதிப்புகளைப் பயன்படுத்தி, அனைத்து N நிகழ்வுகளிலும் ஒரு பூட்டைப் பெற தொடர்ச்சியாக முயற்சிக்கிறது. நிலை 2 இல், கிளையன்ட் ஒரு நிகழ்வின் அடிப்படையில் ஒரு பூட்டை அமைக்கும் போது, ​​பூட்டு தானாக வெளியிடப்படும் நேரத்துடன் ஒப்பிடும் போது, ​​அதை வாங்குவதற்கு வாடிக்கையாளர் தாமதத்தை பயன்படுத்துகிறார். எடுத்துக்காட்டாக, தடுக்கும் காலம் 10 வினாடிகள் என்றால், தாமதமானது ~5-50 மில்லி விநாடிகள் வரம்பில் இருக்கலாம். இது ஒரு தோல்வியுற்ற Redis முனையை அடைவதற்கு நீண்ட காலத்திற்கு கிளையன்ட் தடுக்கப்பட்டிருக்கும் சூழ்நிலையை நீக்குகிறது: நிகழ்வு கிடைக்கவில்லை என்றால், விரைவில் மற்றொரு நிகழ்வை இணைக்க முயற்சிப்போம்.
  3. ஒரு பூட்டை எடுக்க, வாடிக்கையாளர் எவ்வளவு நேரம் கடந்துவிட்டது என்பதைக் கணக்கிடுகிறார்; இதைச் செய்ய, இது படி 1 இல் பெறப்பட்ட நேர முத்திரையை உண்மையான நேர மதிப்பிலிருந்து கழிக்கிறது. கிளையன்ட் பெரும்பாலான நிகழ்வுகளில் (குறைந்தது 3) பூட்டைப் பெற முடிந்தால் மட்டுமே, அது எடுக்கும் மொத்த நேரம் பூட்டைப் பெற, பூட்டு காலத்தை விட குறைவாக, பூட்டு பெறப்பட்டதாகக் கருதப்படுகிறது.
  4. ஒரு பூட்டு வாங்கப்பட்டிருந்தால், பூட்டு காலமானது, படி 3 இல் கணக்கிடப்பட்ட கழிந்த நேரத்தைக் கழித்து அசல் பூட்டு காலமாக எடுத்துக்கொள்ளப்படும்.
  5. சில காரணங்களால் கிளையன்ட் பூட்டைப் பெறத் தவறினால் (அது N/2+1 நிகழ்வுகளைப் பூட்ட இயலவில்லை, அல்லது பூட்டு காலம் எதிர்மறையாக இருந்தால்), அது எல்லா நிகழ்வுகளையும் திறக்க முயற்சிக்கும் (அது தடுக்க முடியாது என்று நினைத்தவை கூட )

அல்காரிதம் ஒத்திசைவற்றதா?

இந்த வழிமுறையானது, அனைத்து செயல்முறைகளும் செயல்படும் ஒத்திசைக்கப்பட்ட கடிகாரம் இல்லை என்றாலும், ஒவ்வொரு செயல்பாட்டிலும் உள்ள உள்ளூர் நேரம் இன்னும் ஏறக்குறைய ஒரே வேகத்தில் பாய்கிறது, மேலும் பூட்டு இருக்கும் மொத்த நேரத்துடன் ஒப்பிடும்போது பிழை சிறியது என்ற அனுமானத்தின் அடிப்படையில் அமைந்துள்ளது. தானாக வெளியிடப்பட்டது. இந்த அனுமானம் சாதாரண கணினிகளுக்கு பொதுவான நிலைமைக்கு மிகவும் ஒத்திருக்கிறது: ஒவ்வொரு கணினிக்கும் உள்ளூர் கடிகாரம் உள்ளது, மேலும் வெவ்வேறு கணினிகளுக்கு இடையிலான நேர வேறுபாடு சிறியதாக இருப்பதை நாம் வழக்கமாக நம்பலாம்.

இந்த கட்டத்தில், எங்கள் பரஸ்பர விலக்கு விதியை நாம் மிகவும் கவனமாக உருவாக்க வேண்டும்: பூட்டை வைத்திருக்கும் கிளையன்ட் பூட்டு செல்லுபடியாகும் நேரத்தில் வெளியேறினால் மட்டுமே பரஸ்பர விலக்குக்கு உத்தரவாதம் அளிக்கப்படும் (படி 3 இல் பெறப்பட்ட மதிப்பு), இன்னும் சில நேரம் கழித்து (மொத்தம் சில செயல்முறைகளுக்கு இடையிலான நேர வேறுபாட்டை ஈடுசெய்ய மில்லி விநாடிகள்).

பின்வரும் சுவாரஸ்யமான கட்டுரை நேர இடைவெளிகளின் ஒருங்கிணைப்பு தேவைப்படும் அத்தகைய அமைப்புகளைப் பற்றி மேலும் கூறுகிறது: குத்தகைகள்: விநியோகிக்கப்பட்ட கோப்பு தற்காலிக சேமிப்பு நிலைத்தன்மைக்கான ஒரு திறமையான தவறு-சகிப்பு நுட்பம்.

தோல்வியில் மீண்டும் முயற்சிக்கவும்

ஒரு கிளையன்ட் பூட்டைப் பெறத் தவறினால், அது சீரற்ற தாமதத்திற்குப் பிறகு மீண்டும் முயற்சிக்க வேண்டும்; ஒரே நேரத்தில் ஒரே வளத்தில் பூட்டைப் பெற முயற்சிக்கும் பல வாடிக்கையாளர்களை ஒத்திசைக்க இது செய்யப்படுகிறது (இது வெற்றியாளர்கள் இல்லாத "பிளவு-மூளை" சூழ்நிலைக்கு வழிவகுக்கும்). கூடுதலாக, பெரும்பாலான ரெடிஸ் நிகழ்வுகளில் ஒரு கிளையன்ட் எவ்வளவு வேகமாகப் பூட்டைப் பெற முயல்கிறாரோ, அவ்வளவுக்குக் குறுகலான சாளரம் மூளையில் பிளவு ஏற்படக்கூடும் (மற்றும் மறு முயற்சிகளின் தேவை குறைவாக இருக்கும்). எனவே, கிளையன்ட் மல்டிபிளெக்சிங்கைப் பயன்படுத்தி SET கட்டளைகளை N நிகழ்வுகளுக்கு ஒரே நேரத்தில் அனுப்ப முயற்சிக்க வேண்டும்.

பெரும்பான்மையான பூட்டுகளைப் பெறத் தவறிய வாடிக்கையாளர்களுக்கு (பகுதியளவு) வாங்கிய பூட்டுகளை வெளியிடுவது எவ்வளவு முக்கியம் என்பதை இங்கே வலியுறுத்துவது மதிப்பு, அதனால் வளத்தின் பூட்டை மீண்டும் பெறுவதற்கு முன்பு சாவி காலாவதியாகும் வரை அவர்கள் காத்திருக்க வேண்டியதில்லை. (நெட்வொர்க் துண்டாடுதல் ஏற்பட்டாலும் , மற்றும் வாடிக்கையாளர் Redis நிகழ்வுகளுடன் தொடர்பை இழந்தாலும், விசை காலாவதியாகும் வரை காத்திருக்கும்போது கிடைக்கும் அபராதம் செலுத்த வேண்டும்).

பூட்டை விடுவிக்கவும்

பூட்டை வெளியிடுவது என்பது ஒரு எளிய செயலாகும், இது கிளையன்ட் ஒரு குறிப்பிட்ட நிகழ்வை வெற்றிகரமாகப் பூட்டியதாகத் தோன்றினாலும், எல்லா நிகழ்வுகளையும் திறக்க வேண்டும்.

பாதுகாப்பு பரிசீலனைகள்

அல்காரிதம் பாதுகாப்பானதா? வெவ்வேறு காட்சிகளில் என்ன நடக்கிறது என்பதை கற்பனை செய்ய முயற்சிப்போம்.

தொடங்குவதற்கு, கிளையன்ட் பெரும்பாலான நிகழ்வுகளில் பூட்டைப் பெற முடிந்தது என்று வைத்துக்கொள்வோம். ஒவ்வொரு நிகழ்விலும் அனைவருக்கும் ஒரே வாழ்நாள் கொண்ட ஒரு சாவி இருக்கும். இருப்பினும், இந்த விசைகள் ஒவ்வொன்றும் வெவ்வேறு நேரத்தில் நிறுவப்பட்டதால், அவை வெவ்வேறு நேரங்களில் காலாவதியாகும். ஆனால், முதல் விசை T1 ஐ விட மோசமான நேரத்தில் நிறுவப்பட்டிருந்தால் (முதல் சேவையகத்தைத் தொடர்புகொள்வதற்கு முன் நாங்கள் தேர்வு செய்யும் நேரம்), மற்றும் கடைசி விசை T2 ஐ விட மோசமான நேரத்தில் நிறுவப்பட்டது (பதில் பெறப்பட்ட நேரம் கடைசி சர்வரில் இருந்து), பின்னர் காலாவதியாகும் தொகுப்பின் முதல் விசை குறைந்தபட்சம் உயிர்வாழும் என்று நாங்கள் நம்புகிறோம் MIN_VALIDITY=TTL-(T2-T1)-CLOCK_DRIFT. மற்ற அனைத்து விசைகளும் பின்னர் காலாவதியாகும், எனவே அனைத்து விசைகளும் குறைந்தபட்சம் இந்த நேரத்திற்காவது ஒரே நேரத்தில் செல்லுபடியாகும் என்பதை உறுதியாக நம்பலாம்.

பெரும்பாலான விசைகள் செல்லுபடியாகும் நேரத்தில், மற்றொரு கிளையன்ட் பூட்டைப் பெற முடியாது, ஏனெனில் N/2+1 விசைகள் ஏற்கனவே இருந்தால் N/2+1 SET NX செயல்பாடுகள் வெற்றியடையாது. எனவே, ஒரு பூட்டை வாங்கியவுடன், அதே நேரத்தில் அதை மீண்டும் பெற முடியாது (இது பரஸ்பர விலக்கு சொத்தை மீறும்).
இருப்பினும், ஒரே நேரத்தில் பூட்டைப் பெற முயற்சிக்கும் பல கிளையன்ட்கள் ஒரே நேரத்தில் வெற்றிபெற முடியாது என்பதை உறுதிப்படுத்த விரும்புகிறோம்.

கிளையன்ட் பெரும்பாலான நிகழ்வுகளை அதிகபட்ச பூட்டு காலத்திற்கு அல்லது அதற்கு மேல் பூட்டியிருந்தால், அது பூட்டை செல்லாததாகக் கருதி, நிகழ்வுகளைத் திறக்கும். எனவே, காலாவதி தேதியை விட குறைவான நேரத்தில் பெரும்பாலான நிகழ்வுகளை கிளையன்ட் தடுக்க முடிந்ததை மட்டுமே நாங்கள் கணக்கில் எடுத்துக்கொள்ள வேண்டும். இந்த நிலையில், மேற்படி வாதம் தொடர்பாக, காலத்தின் போது MIN_VALIDITY எந்த வாடிக்கையாளரும் பூட்டை திரும்பப் பெற முடியாது. எனவே, பல கிளையன்ட்கள் N/2+1 நிகழ்வுகளை ஒரே நேரத்தில் பூட்ட முடியும் (இது நிலை 2 இன் முடிவில் முடிவடையும்) பெரும்பான்மையை பூட்டுவதற்கான நேரம் TTL நேரத்தை விட அதிகமாக இருக்கும் போது மட்டுமே, பூட்டை செல்லாததாக மாற்றும்.

பாதுகாப்புக்கான முறையான ஆதாரத்தை வழங்க முடியுமா, ஏற்கனவே உள்ள ஒத்த அல்காரிதம்களைக் குறிப்பிட முடியுமா அல்லது மேலே உள்ள பிழையைக் கண்டறிய முடியுமா?

அணுகல் பரிசீலனைகள்

கணினியின் கிடைக்கும் தன்மை மூன்று முக்கிய பண்புகளை சார்ந்துள்ளது:

  1. பூட்டுகளை தானாக விடுவித்தல் (விசைகள் காலாவதியாகும்போது): பூட்டுகளுக்குப் பயன்படுத்த விசைகள் இறுதியில் மீண்டும் கிடைக்கும்.
  2. விரும்பிய பூட்டு பெறப்படாதபோது அல்லது கையகப்படுத்தப்பட்டு வேலை முடிந்ததும் வாடிக்கையாளர்கள் பொதுவாக பூட்டுகளை அகற்றுவதன் மூலம் ஒருவருக்கொருவர் உதவுகிறார்கள். எனவே பூட்டை மீண்டும் பெறுவதற்கு விசைகள் காலாவதியாகும் வரை நாம் காத்திருக்க வேண்டியதில்லை.
  3. ஒரு கிளையண்ட் ஒரு பூட்டைப் பெற மீண்டும் முயற்சிக்க வேண்டியிருக்கும் போது, ​​பெரும்பாலான பூட்டுகளைப் பெறுவதற்குத் தேவைப்படும் காலத்தை விட ஒப்பீட்டளவில் நீண்ட நேரம் காத்திருக்கிறது. இது வளங்களுக்காக போட்டியிடும் போது ஏற்படும் பிளவு-மூளை சூழ்நிலையின் வாய்ப்பைக் குறைக்கிறது.

இருப்பினும், நெட்வொர்க் பிரிவுகளின் TTL க்கு சமமான கிடைக்கும் அபராதம் உள்ளது, எனவே தொடர்ச்சியான பிரிவுகள் இருந்தால், அபராதம் காலவரையின்றி இருக்கலாம். ஒரு கிளையன்ட் ஒரு பூட்டைப் பெற்று, அதை வெளியிடுவதற்கு முன் மற்றொரு பிரிவிற்கு கிழித்தெறியப்படும் போதெல்லாம் இது நடக்கும்.

கொள்கையளவில், எல்லையற்ற தொடர்ச்சியான நெட்வொர்க் பிரிவுகள் கொடுக்கப்பட்டால், ஒரு அமைப்பு எல்லையற்ற காலத்திற்கு கிடைக்காமல் இருக்கும்.

செயல்திறன், தோல்வி மற்றும் fsync

பலர் ரெடிஸைப் பயன்படுத்துகின்றனர், ஏனெனில் பூட்டுகளைப் பெறுவதற்கும் வெளியிடுவதற்கும் தேவைப்படும் தாமதம் மற்றும் ஒரு வினாடிக்கு முடிக்கக்கூடிய கையகப்படுத்துதல்/வெளியீடுகளின் எண்ணிக்கை ஆகியவற்றின் அடிப்படையில் அவர்களுக்கு உயர் பூட்டு சேவையக செயல்திறன் தேவைப்படுகிறது. இந்த தேவையை பூர்த்தி செய்ய, தாமதத்தை குறைக்க N Redis சேவையகங்களுடன் தொடர்பு கொள்ள ஒரு உத்தி உள்ளது. இது ஒரு மல்டிபிளெக்சிங் உத்தி (அல்லது "ஏழையின் மல்டிபிளெக்சிங்", அங்கு சாக்கெட் தடையற்ற பயன்முறையில் வைக்கப்பட்டு, அனைத்து கட்டளைகளையும் அனுப்புகிறது, மேலும் கிளையன்ட் மற்றும் ஒவ்வொரு நிகழ்விற்கும் இடையிலான சுற்று-பயண நேரம் ஒத்ததாக இருக்கும் என்று கருதி, கட்டளைகளை பின்னர் படிக்கும்) .

இருப்பினும், தோல்விகளில் இருந்து நம்பகமான மீட்சியுடன் ஒரு மாதிரியை உருவாக்க முயற்சித்தால், நீண்ட கால தரவு சேமிப்பகத்துடன் தொடர்புடைய பரிசீலனையையும் நாம் கணக்கில் எடுத்துக்கொள்ள வேண்டும்.

அடிப்படையில், சிக்கலைத் தெளிவுபடுத்த, நீண்ட கால தரவுச் சேமிப்பகம் இல்லாமல் Redis ஐ உள்ளமைக்கிறோம் என்று வைத்துக்கொள்வோம். கிளையன்ட் 3 இல் 5 நிகழ்வுகளைத் தடுக்க நிர்வகிக்கிறார். கிளையண்ட் தடுக்க முடிந்த நிகழ்வுகளில் ஒன்று மறுதொடக்கம் செய்யப்பட்டது, இந்த நேரத்தில் அதே ஆதாரத்திற்கு மீண்டும் 3 நிகழ்வுகள் உள்ளன, அதை நாங்கள் தடுக்கலாம், மேலும் மற்றொரு கிளையன்ட் மறுதொடக்கம் செய்யப்பட்ட நிகழ்வைத் தடுக்கலாம், இது பாதுகாப்புச் சொத்தை மீறுகிறது. பூட்டுகளின் பிரத்தியேகத்தை கருதுகிறது.

நீங்கள் டேட்டாவை முன்னோக்கி (AOF) இயக்கினால், நிலைமை சற்று மேம்படும். எடுத்துக்காட்டாக, SHUTDOWN கட்டளையை அனுப்பி அதை மறுதொடக்கம் செய்வதன் மூலம் நீங்கள் ஒரு சேவையகத்தை விளம்பரப்படுத்தலாம். ரெடிஸில் காலாவதியான செயல்பாடுகள், சர்வர் ஆஃப் செய்யப்பட்டிருந்தாலும், நேரம் தொடர்ந்து செல்லும் வகையில் சொற்பொருளியல் முறையில் செயல்படுத்தப்படுவதால், எங்களின் தேவைகள் அனைத்தும் நன்றாக உள்ளன. சாதாரண பணிநிறுத்தம் உறுதிசெய்யப்படும் வரை இது இயல்பானது. மின்சாரம் தடைபட்டால் என்ன செய்வது? ரெடிஸ் முன்னிருப்பாக கட்டமைக்கப்பட்டிருந்தால், fsync ஒவ்வொரு நொடியும் வட்டில் ஒத்திசைக்கப்படுகிறது, மறுதொடக்கம் செய்த பிறகு எங்களிடம் விசை இருக்காது. கோட்பாட்டளவில், எந்தவொரு நிகழ்வையும் மறுதொடக்கம் செய்யும் போது பூட்டு பாதுகாப்பிற்கு உத்தரவாதம் அளிக்க விரும்பினால், நாங்கள் இயக்க வேண்டும் fsync=always நீண்ட கால தரவு சேமிப்பிற்கான அமைப்புகளில். விநியோகிக்கப்பட்ட பூட்டுகளைப் பாதுகாப்பாகச் செயல்படுத்த பாரம்பரியமாகப் பயன்படுத்தப்படும் CP அமைப்புகளின் அளவிற்கு இது செயல்திறனை முற்றிலுமாக அழிக்கும்.

ஆனால் முதல் பார்வையில் தோன்றுவதை விட நிலைமை சிறப்பாக உள்ளது. கொள்கையளவில், அல்காரிதத்தின் பாதுகாப்பு பாதுகாக்கப்படுகிறது, ஏனெனில் தோல்விக்குப் பிறகு நிகழ்வு மறுதொடக்கம் செய்யப்படும் போது, ​​அது தற்போது செயலில் உள்ள எந்த பூட்டிலும் பங்கேற்காது.

இதை உறுதிப்படுத்த, ஒரு தோல்விக்குப் பிறகு, நாம் பயன்படுத்தும் அதிகபட்ச TTL ஐ விட சிறிது காலத்திற்கு அந்த நிகழ்வு கிடைக்காமல் இருப்பதை உறுதி செய்ய வேண்டும். இந்த வழியில் காலாவதி தேதி மற்றும் தோல்வி நேரத்தில் செயலில் இருந்த அனைத்து விசைகளின் தானியங்கி வெளியீடு வரை காத்திருப்போம்.

தாமதமான மறுதொடக்கங்களைப் பயன்படுத்தி, ரெடிஸில் எந்த நீண்ட கால நிலைத்தன்மையும் இல்லாவிட்டாலும் பாதுகாப்பை அடைவது கொள்கையளவில் சாத்தியமாகும். இருப்பினும், அணுகலை மீறுவதற்கு இது அபராதம் விதிக்கப்படலாம் என்பதை நினைவில் கொள்க. எடுத்துக்காட்டாக, பெரும்பாலான நிகழ்வுகள் தோல்வியுற்றால், கணினி உலகளவில் TTL க்கு கிடைக்காமல் போகும் (மேலும் இந்த நேரத்தில் எந்த ஆதாரத்தையும் தடுக்க முடியாது).

அல்காரிதம் கிடைப்பதை அதிகரிக்கிறோம்: தடுப்பதை நீட்டிக்கிறோம்

வாடிக்கையாளர்களால் செய்யப்படும் வேலை சிறிய படிகளைக் கொண்டிருந்தால், இயல்புநிலை பூட்டு காலத்தை குறைத்து, பூட்டுகளை நீட்டிப்பதற்கான ஒரு பொறிமுறையை செயல்படுத்த முடியும். கொள்கையளவில், கிளையன்ட் கம்ப்யூட்டிங்கில் மும்முரமாக இருந்தால் மற்றும் பூட்டு காலாவதி மதிப்பு அபாயகரமாக குறைவாக இருந்தால், விசையின் TTL ஐ நீட்டிக்கும் அனைத்து நிகழ்வுகளுக்கும் லுவா ஸ்கிரிப்டை அனுப்பலாம் மற்றும் அதன் மதிப்பு இன்னும் சீரற்ற மதிப்பாக இருந்தால், பூட்டு பெறப்பட்டது.

செல்லுபடியாகும் காலத்திற்குள் பெரும்பாலான நிகழ்வுகளை பூட்ட முடிந்தால் மட்டுமே ஒரு பூட்டை மீண்டும் பெறுவதற்கு கிளையன்ட் கருத வேண்டும்.

உண்மை, தொழில்நுட்ப ரீதியாக அல்காரிதம் மாறாது, எனவே பூட்டுகளைப் பெறுவதற்கான தொடர்ச்சியான முயற்சிகளின் அதிகபட்ச எண்ணிக்கை குறைவாக இருக்க வேண்டும், இல்லையெனில் அணுகல் பண்புகள் மீறப்படும்.

ஆதாரம்: www.habr.com

கருத்தைச் சேர்