• 0 رای - 0 میانگین
  • 1
  • 2
  • 3
  • 4
  • 5
راهنمایی درباره ارسال مقادیر فرم در سایت های پرترافیک
#1
سلام خدمت اساتید گرامی
سوالی داشتم و ممنون میشم من رو راهنمایی کنید

من یک سایت خدماتی دارم که توی سایت یک سری کالا معرفی میکنم برای ثبت نام و خریدشون
شما فرض کنید یک محصول تعریف شده و تعداد 700 تا 2000 نفر (که این برای بعضی محصولات پرطرفدار فرق میکنه) همزمان در سایت آنلاین هستند و منتظرن که ثبت نام محصول شروع بشه

من برای این سایت از کدایگنایتر و دیتابیس mysql  و فرمت دیتابیس INNODB استفاده کردم

* یکسری فیلتر ها هم روی افرادی که ثبت نام میکنن اعمال میشه

سوال اول :  آیا INNODB این کارایی رو داره که این حجم از کسانی که همزمان دارن فرم رو ارسال میکنن رو یکی یکی تشخیص بده و وارد دیتابیس کنه ؟

سوال دوم : در صورت استفاده از INNODB آیا استفاده از یک تاخییر چند میلی ثانیه ای مثل استفاده از تابع usleep در php  میتونه کمی ارسال هایی که به صورت همزمان ارسال شدند رو کنترل کنه ؟ من دارم از تولید زمان رندوم برای تاخییر استفاده میکنم

سوال سوم : ایجاد این تاخییر فشار زیادی روی سرور میاره ؟ با توجه به اینکه تاخییرهایی که اتفاق میفت کاملا رندوم هست از 0.1 تا 2 ثانیه


ممنون میشم در این باره راهنمایی کنید
  پاسخ
تشکر شده توسط :
#2
سلام ، از اساتید کسی راهنمایی نمیکنه؟
  پاسخ
تشکر شده توسط :
#3
میتونی lock کنی تیبل رو یا از queue استفاده بکنی .
وبلاگ rezaonline.net/blog
سفارش برنامه نویسی reza.biz
Php , mysql , postgresql , redis , Yii and ... Cool
  پاسخ
تشکر شده توسط : kasbookar
#4
ممنون رضا جان ، یک سوال آیا لاک کردن تیبل باعث ایجاد شلوغی در دیتابیس و یا فشار به سرور نمیشه ؟
شما اینطور فرض کن در آخرین بار که ثبت نام بود در عرض حدود 30 ثانیه 1000 تا درخواست ثبت نام ارسال شد (البته فرایند بررسی ثبت نام هم زیاد سخت نیست در بک اند)
اینطور بگم 3000 نفر در 6 دقیقه ثبت نام میکنن

و ممنون میشم لینک های معتبری رو برای لاک کردن و در صف گذاشتن بفرستی تا مطالعه کنم

لطفا ببین آیا این طور نوشتن کد برای بروز رسانی یک رکورد از جدول درسته ؟و برای ارسال فرم های پر ترافیک جوابگو هست ؟
کد پی‌اچ‌پی:
     $this->db->query('LOCK TABLE Table1 WRITE , Table3 WRITE, Table3 WRITE');
 
       $this->db->query("UPDATE `Table1` SET `user_information`='Megdar' WHERE id=?");
 
       return $this->db->affected_rows();
 
     $this->db->query('UNLOCK TABLES'); 
  پاسخ
تشکر شده توسط :
#5
اگر میتونی دیتا رو async کنی از queue استفاده کن در غیر اینصورت باید lockکنی .

https://www.mysqltutorial.org/mysql-tabl...r%20itself.

من یک سیستم حسابداری نوشته بودم و برای موجودی ها از همین lock استفاده کردم روی دیتابیس postgresql و تونستم rps 800 رو ازش بگیرم .

اگه بتونی از mysql 100هم بگیری توی 30 ثانیه میشه 3000 که فکر کنم جوابگوی کارت هست و یه چیزی هم در مورد lock بدون اینکه wait میکنه درخواست رو یعنی اگه تعداد بیشتری هم بیان نمیرن توی دیوار ، یخورده کند میشه و جواب میده .

علتش هم منطقی هست دیگه یک قیف رو در نظر بگیر که از سر بزرگ وارد میشن و از سر کوچیک خارج میشن .
وبلاگ rezaonline.net/blog
سفارش برنامه نویسی reza.biz
Php , mysql , postgresql , redis , Yii and ... Cool
  پاسخ
تشکر شده توسط : kasbookar
#6
اگر هم میتونی چنین سناریویی بذاری که همه رو ثبت نام کنی و بعد بگی که در حال پردازش هست و بعد از یکی دو دقیقه بهشون بگی که عملیات انجام شده یا نه (async بودن)
میتونی از queue استفاده بکنی بدون درد و خونریزی Smile

https://github.com/yidas/codeigniter-queue-worker
وبلاگ rezaonline.net/blog
سفارش برنامه نویسی reza.biz
Php , mysql , postgresql , redis , Yii and ... Cool
  پاسخ
تشکر شده توسط : kasbookar
#7
ممنون از استاد عزیزم رضا جان
حرف queue رو نزنیم بهتره ، چون توی این سیستم من باید همزمان هر کسی درخواست داد نتیجشو ببینه
فک کنم باید از لاک استفاده کنم
چون ببین توی ثبت نام های قبلی مشکلی که بود ، برای مثال حداکثر 2000 نفر میتونستن عضو بشن ، خب ثبت نام شرو میشد و از این تعداد 2000 نفر توی سیستم ثبت میشد
و به اینها پیامی مبنی بر اینکه ثبت نام شدن نشون میداد
علاوه بر اینها به تعدادی هم پیام ثبت نام موفق نشون میداد در حالی که در سیستم ثبت نشده بودن

این مشکل از لاک نکردن تیبل هنگام بروزرسانی تیبل اتفاق میفتاد درسته ؟

رضا جان الان یک سوال
منکه میام قبل از بروزرسانی تیبل و رکورد مورد نظر اون رو با LOCK TABLE Table1 WRITE برای نوشتن lock میکنم خب قبل اینهم یکسری افرادی که در خواست دادن برای ثبت نام ، سیستم باید تعداد نفراتی که ثبت نام کردن رو هم بخونه ، آیا هنگام لاک کردن تیبل برای نوشتن باید این تیبل رو هم LOCK TABLE Table1 READ کنم ؟
یا اینکه با LOCK TABLE Table1 WRITE کردن بخش READ هم به صورت خودکار لاک میشه ؟

سوال دوم : اگه تیبل قابل READ شدن نباشه و کسی بخواد READ کنه ایا باید اروری برای اینکار هندل کرد ؟
یا این موضوع توسط خود سیستم رد میشه یا برای READ کردن اون درخواست رو هم در حالت Wait قرار میده ؟
  پاسخ
تشکر شده توسط : Reza
#8
مشکلت میشه همزمانی concurrency اگه خواستی این کلید واژه رو سرچ بزن .

در خصوص مشکلت هم من اینجور فهمیدم که تو یک مقداری داری که به هر یوزر یکی میدی و این هی کم میشه تا به صفر برسه .

خب یک جدول بساز به اسم log و فیلد user_id , balance رو توش بریز
بعد رکورد اول رو بده 0 و 2000

حالا یک ترنزکشن درست کن begin transaction
و write تیبل رو ببند

LOCK TABLES log WRITE

اینجا نوشتن رو بستی و میتونی بخونی پس بیا آخرین مقدار رو بخون
select balance from log order by id desc limit 1

بعد اگر مخالف صفر بود -1 بکن و دستور insert رو بزن
insert into log (user_id,balance) values (2,1999)

بعد تیبل رو آنلاک کن
UNLOCK TABLES

بعد ترنزکشن رو کامیت کن بره .

اگرم اکسپشن خورد که رول بک بزن .
وبلاگ rezaonline.net/blog
سفارش برنامه نویسی reza.biz
Php , mysql , postgresql , redis , Yii and ... Cool
  پاسخ
تشکر شده توسط :
#9
کد پی‌اچ‌پی:
       try {
 
         $this->db->trans_begin();
 
         $this->db->query('LOCK TABLE RegisterUsers WRITE , copacity_stores WRITE, copacity_stores2 WRITE');

 
         $max $this->sql->fetch_data_object("MaxValue","*","id",$kala);
 
         $max $max[0]->max_count_product  //حداکثر مقدار تعیین شده
 
         $Count $this->sql->fetch_data_object("RegisterUsers","*","id",$kala); // شمارش کسانی که ثبت نام کرده اند
 
         $check_national_code_unserializeCount unserialize($Count[0]->user_informations);


 
         //مقایسه برای اینکه ظرفیت تکمیل شده یا نه
 
         if(count($check_national_code_unserializeCount) >= $max)
 
         {
 
           echo "ظرفیت تکمیل شد";
 
           exit();
 
         }
 
         else{
 
           
            $merged_informations 
$check_national_code_unserialize+$data_user// اضافه کردن آرایه جدید کاربری که میخواد ثبت نام کنه به ارایه های قبلی در دیتابیس
 
           $data serialize($merged_informations);
 
           $this->db->query("UPDATE `RegisterUsers` SET `user_informations`='$data' WHERE `id`=$kala"); //بروزرسانی کردن دیتابیس
 
           $this->sumMaxStores2($kala,$store); // بروزرسانی تعداد کل ثبت نام کنندگان در دیتابیس با روش +1
 
         }
 
         $this->db->query('UNLOCK TABLES'); // بازکردن قفل جداول
 
         $this->db->trans_commit(); //تایید تراکنش
 
       }
 
       catch(Exception $e) {
 
         $this->db->trans_rollback(); // برگشت تراکنش
 
       
خب رضا جان ، من الان اون موارد رو پیاده کردم ممنون میشم از لحاظ ساختاری که گفتی ، بررسی کنی ببینی درسته ؟ آیا transaction و commit رو جای خودشون استفاده کردم ؟
  پاسخ
تشکر شده توسط :
#10
فکر کنم درسته ، تستشم بکن توی لوپ بذار با ab هزار رکوئست بده ببین درست کار میکنه یا نه
وبلاگ rezaonline.net/blog
سفارش برنامه نویسی reza.biz
Php , mysql , postgresql , redis , Yii and ... Cool
  پاسخ
تشکر شده توسط :


پرش به انجمن:


کاربران در حال بازدید این موضوع: 1 مهمان