7.1 அது ஏன் அவசியம்

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

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

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

7.2 பரிவர்த்தனை பிரியர்களுக்கான அடிப்படை கருவிகள்

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

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

உதாரணமாக, ஒரு டெவலப்பரின் தினசரி வாழ்க்கையிலிருந்து ஒரு தொழில்நுட்பத்தை நான் கண்டறிந்தேன், அது நம்பிக்கையான பூட்டுதல் போன்ற ஒன்றைப் பயன்படுத்துகிறது - இது HTTP நெறிமுறை. ஆரம்ப HTTP GET கோரிக்கைக்கான பதிலில் கிளையண்டின் அடுத்தடுத்த PUT கோரிக்கைகளுக்கான ETag தலைப்பு இருக்கலாம், இதை கிளையன்ட் If-Match தலைப்பில் பயன்படுத்தலாம். GET மற்றும் HEAD முறைகளுக்கு, சேவையகம் தனக்குத் தெரிந்த ETtagகளில் ஏதேனும் ஒன்றைப் பொருத்தினால் மட்டுமே கோரப்பட்ட ஆதாரத்தை திருப்பி அனுப்பும். PUT மற்றும் பிற பாதுகாப்பற்ற முறைகளுக்கு, இது இந்த விஷயத்திலும் மட்டுமே ஆதாரத்தை ஏற்றும். ETag எவ்வாறு இயங்குகிறது என்பது உங்களுக்குத் தெரியாவிட்டால், "ஃபீட்பார்சர்" லைப்ரரியைப் பயன்படுத்துவதற்கான சிறந்த உதாரணம் இதோ (இது RSS மற்றும் பிற ஊட்டங்களை அலச உதவுகிறது).


>>> import feedparser 
>>> d = feedparser.parse('http://feedparser.org/docs/examples/atom10.xml') 
>>> d.etag 
'"6c132-941-ad7e3080"' 
>>> d2 = feedparser.parse('http://feedparser.org/docs/examples/atom10.xml', etag=d.etag) 
>>> d2.feed 
{} 
>>> d2.debug_message 
'The feed has not changed since you last checked, so the server sent no data.  This is a feature, not a bug!' 

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

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

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

பூட்டுகளை செயல்படுத்துவது குறித்து. நான் விவரங்களுக்கு செல்ல விரும்பவில்லை, ஆனால் விநியோகிக்கப்பட்ட அமைப்புகளுக்கு பூட்டு மேலாளர்கள் உள்ளனர், எடுத்துக்காட்டாக: ZooKeeper, Redis, etcd, Consul.

7.3 செயல்பாடுகளின் இயலாமை

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

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

இது ஒரு தூய செயல்பாடு:


def square(num: int) -> int: 
	return num * num 

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


def insert_data(insert_query: str, db_connection: DbConnectionType) -> int: 
  db_connection.execute(insert_query) 
  return True 

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

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

மாற்றத்திற்கு, நான் மற்றொரு உதாரணம் தருகிறேன் - ஏபிஐக்கு ("விகித வரம்பு") கோரிக்கைகளின் அதிர்வெண்ணைக் கட்டுப்படுத்துகிறது. எங்கள் லாம்ப்டா ஒரு குறிப்பிட்ட பயனர்_ஐடியுடன் ஒரு நிகழ்வைப் பெறுகிறது, அதற்காக அந்த ஐடியைக் கொண்ட பயனர் எங்களின் சில API களுக்கு சாத்தியமான கோரிக்கைகளின் எண்ணிக்கையை முடித்துவிட்டாரா என்பதைச் சரிபார்க்க வேண்டும். AWS இலிருந்து DynamoDB இல் செய்யப்படும் அழைப்புகளின் மதிப்பை நாம் சேமித்து வைக்கலாம், மேலும் ஒவ்வொரு அழைப்பின் போதும் அதை 1 ஆல் அதிகரிக்கலாம்.

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

import json
import os
from typing import Any, Dict

from aws_lambda_powertools.utilities.typing import LambdaContext  # needed only for argument type annotation
import boto3

limit = os.getenv('LIMIT')

def handler_name(event: Dict[str: Any], context: LambdaContext):

	request_id = context.aws_request_id

	# We find user_id in incoming event
	user_id = event["user_id"]

	# Our table for DynamoDB
	table = boto3.resource('dynamodb').Table('my_table')

	# Doing update
	table.update_item(
    	Key={'pkey': user_id},
    	UpdateExpression='ADD requests :request_id',
    	ConditionExpression='attribute_not_exists (requests) OR (size(requests) < :limit AND NOT contains(requests, :request_id))',
    	ExpressionAttributeValues={
        	':request_id': {'S': request_id},
        	':requests': {'SS': [request_id]},
        	':limit': {'N': limit}
    	}
	)

	# TODO: write further logic

	return {
    	"statusCode": 200,
    	"headers": {
        	"Content-Type": "application/json"
    	},
    	"body": json.dumps({
        	"status ": "success"
    	})
	}

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

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