<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
    <channel>
        <title>نوشته های Mohammad Javad Naderi</title>
        <link>https://virgool.io/feed/@mjnaderi</link>
        <description>هم‌بنیان‌گذار Quera، یک مهندس نرم‌افزار دانشگاهی در تلاش برای تبدیل شدن به یک مهندس واقعی</description>
        <language>fa</language>
        <pubDate>2026-06-17 07:35:12</pubDate>
        <image>
            <url>https://files.virgool.io/upload/users/34572/avatar/sJtvhv.png?height=120&amp;width=120</url>
            <title>Mohammad Javad Naderi</title>
            <link>https://virgool.io/@mjnaderi</link>
        </image>

                    <item>
                <title>برخی امکانات جدید زبان پایتون</title>
                <link>https://virgool.io/@mjnaderi/%D9%85%D8%B9%D8%B1%D9%81%DB%8C-%D8%A8%D8%B1%D8%AE%DB%8C-%D8%A7%D9%85%DA%A9%D8%A7%D9%86%D8%A7%D8%AA-%D8%AC%D8%AF%DB%8C%D8%AF-%D8%B2%D8%A8%D8%A7%D9%86-%D9%BE%D8%A7%DB%8C%D8%AA%D9%88%D9%86-hopdkiet1czm</link>
                <description>حدود دو ماه از انتشار پایتون ۳٫۸ می‌گذرد. در زمان انتشار پایتون ۳٫۸ در تیم فنی شرکت برخی از امکانات جدید پایتون (در نسخه‌های ۳٫۶، ۳٫۷ و ۳٫۸) را ارائه دادم. در این مطلب می‌خواهم بخش‌هایی از آن ارائه را معرفی کنم.سعی می‌کنم کوتاه و مختصر بنویسم تا در کمترین زمان با این ویژگی‌ها آشنا شوید و برای تمرین بیشتر خودتان آن‌ها را امتحان کنید. به جای توضیحات مفصل، سعی کرده‌ام تکه‌کدهایی قرار دهم که با خواندن آن‌ها با امکانات جدید بهتر آشنا شوید.تصویر از realpython.comدیکشنری ترتیب را حفظ می‌کند (پایتون ۳٫۷)از پایتون ۳٫۶ به بعد، کلیدهای یک دیکشنری ترتیب وارد شدن به دیکشنری را حفظ می‌کنند. یعنی مثلاً وقتی با یک حلقه روی محتوای یک دیکشنری حرکت کنیم، می‌توانیم مطمئن باشیم که مقادیر را به همان ترتیبی که وارد دیکشنری شده‌اند می‌بینیم.&gt;&gt;&gt; d = {}
&gt;&gt;&gt; d[&amp;quota&amp;quot] = 1
&gt;&gt;&gt; d[&amp;quotb&amp;quot] = 2
&gt;&gt;&gt; d.items()
dict_items([(&#039;a&#039;, 1), (&#039;b&#039;, 2)])  # Order is guaranteed
&gt;&gt;&gt; d.keys()
dict_keys([&#039;a&#039;, &#039;b&#039;])  # Order is guaranteedپیش از این اگر به این ویژگی نیاز داشتیم مجبور بودیم از نوع OrderedDict استفاده کنیم.در پایتون ۳٫۶ نوع dict به روش دیگری پیاده‌سازی شده که علاوه بر حفظ ترتیب کلیدها، ۲۰ تا ۲۵ درصد حافظۀ کمتری مصرف می‌کند. ویژگی حفظ ترتیب کلیدها در پایتون ۳٫۶ جزء تعریف زبان نبود، و به خاطر پیاده‌سازی جدید ایجاد شد. اما در پایتون ۳٫۷، این ویژگی رسماً به تعریف (Specification) زبان اضافه شد.ساخت رشته با f-string (پایتون ۳٫۶)حتماً پیشوندهای r یا b را قبل از رشته‌ها دیده‌اید (که به ترتیب برای ایجاد raw string و دادۀ باینری یا bytes به کار می‌روند). اکنون شما را با پیشوند f آشنا می‌کنم که در پایتون ۳٫۶ اضافه شده است:&gt;&gt;&gt; name = &amp;quotFred&amp;quot
&gt;&gt;&gt; print(f&amp;quotHe said his name is {name}.&amp;quot)
He said his name is Fred.

&gt;&gt;&gt; width = 10
&gt;&gt;&gt; precision = 4
&gt;&gt;&gt; value = decimal.Decimal(&amp;quot12.34567&amp;quot)
&gt;&gt;&gt; print(f&amp;quotresult: {value:{width}.{precision}}&amp;quot)  # nested fields
result:      12.35همان‌طور که می‌بینید با استفاده از این ویژگی format کردن یک رشته و قرار دادن مقدار یک متغیر داخل آن بسیار ساده‌تر شده است. توجه کنید که لازم نیست داخل آکولاد تنها نام یک متغیر بیاید. بلکه می‌توان هر عبارتی را داخل آکولاد قرار داد. مثلاً:&gt;&gt;&gt; from math import sin, radians
&gt;&gt;&gt; theta = 30
&gt;&gt;&gt; print(f&amp;quotsin({theta} deg) = {sin(radians(theta)):.3f}&amp;quot)
sin(30 deg) = 0.500 در پایتون ۳٫۸ ویژگی جدیدی به f-string اضافه شده که برای دیباگ کردن خیلی به کار می‌آید. با قرار دادن یک = در انتهای عبارتی که درون آکولاد قرار داده‌اید، خود عبارت نیز در رشته ظاهر می‌شود:&gt;&gt;&gt; from math import sin, radians
&gt;&gt;&gt; theta = 30
&gt;&gt;&gt; print(f&#039;{theta=}  {sin(radians(theta))=:.3f}&#039;)
theta=30  sin(radians(theta))=0.500عملگر Walrus (پایتون ۳٫۸)در پایتون ۳٫۸ عملگر جدید := برای ایجاد عبارت انتسابی (Assignment Expression) به زبان پایتون اضافه شده است. این عملگر، Walrus (گراز دریایی) نام دارد، زیرا شکل این عملگر به چشم‌ها و دندان‌های گراز دریایی شباهت دارد :)یک گراز دریاییاین ویژگی که در PEP 572 مطرح شد، یکی از جنجالی‌ترین ویژگی‌های پایتون بوده است. بحث‌هایی که مطرح شد در نهایت باعث شد Guido van Rossum خالق پایتون از سِمت خود به عنوان BDFL کناره‌گیری کند.I&#x27;m tired, and need a very long break.-- Guido van Rossumبا این عملگر می‌توانیم یک مقدار را به یک متغیر نسبت دهیم و همزمان از آن به عنوان یک عبارت (Expression) استفاده کنیم. تکه‌کد زیر را در نظر بگیرید که یک فایل را باز می‌کند و خط‌های آن را می‌خواند و پردازش می‌کند.fp = open(&#039;some/file.txt&#039;)
while True:
    line = fp.readline()
    if not line:
        break
    process(line)با استفاده از عملگر := می‌توان کد بالا را به این صورت نوشت:fp = open(&#039;some/file.txt&#039;)
while line := fp.readline():
    process(line)در تکه‌کد بالا عبارت line := fp.readline() یک خط را از فایل می‌خواند، خروجی را در متغیر line قرار می‌دهد و همزمان این مقدار را در اختیار while می‌گذارد.فرض کنید تابع fib را پیاده‌سازی کرده‌ایم که n را می‌گیرد و nاُمین عدد فیبوناچی را برمیگرداند. می‌خواهیم همۀ اعداد فیبوناچی کوچکتر از ۱۰۰۰ را چاپ کنیم:i = 0
while (f := fib(i := i + 1)) &lt; 1000:
    print(f)کاربرد این عملگر در کار با کتابخانه re را در مثال زیر می‌بینید:discount = 0.0
if m := re.search(r&#039;(\d+)% discount&#039;, advertisement):
    discount = float(m.group(1)) / 100.0در مثال زیر، بدون عملگر := مجبور بودیم تابع normalize را برای هر name دو بار صدا کنیم، یا اینکه از list comprehension استفاده نکنیم و لیست موردنظر را با یک حلقۀ for معمولی بسازیم.[clean_name.title() for name in names
 if (clean_name := normalize(&#039;NFC&#039;, name)) in allowed_names]برای آشنایی بیشتر با این عملگر توصیه می‌کنم ارائۀ Dustin Ingram در همایش PyCon 2019 را ببینید:https://www.youtube.com/watch?v=6uAvHOKofws پارامترهای positional-only (پایتون ۳٫۸)شاید با پارامترهای keyword-only در پایتون آشنا باشید. در پایتون می‌توانیم تعدادی از پارامترهای یک تابع را به صورت keyword-only در نظر بگیریم. به این معنی که موقع صدازدن تابع، آن پارامترها حتماً باید به صورت keyword argument به تابع پاس داده شوند. در پایتون ۳٫۸، امکان مشخص کردن تعدادی از پارامترهای تابع به صورت positional-only نیز اضافه شده است.تابع زیر را در نظر بگیرید. در این تابع، پارامترهای a و b، پارامترهای positional-only و پارامترهای e و f پارامترهای keyword-only هستند.def f(a, b, /, c, d, *, e, f):
    ...بنابراین هنگام صدا زدن تابع f، برای پاس دادن مقادیر a و b و e و f با محدودیت‌هایی روبرو هستیم. اما پارامترهای c و d می‌توانند به هر دو شکل positional و keyword پاس داده شوند.سه حالت زیر را برای صدا زدن تابع f در نظر بگیرید:f(10, 20, 30, d=40, e=50, f=60)       # Valid
f(10, b=20, c=30, d=40, e=50, f=60)   # Invalid
f(10, 20, 30, 40, 50, f=60)           # Invalidمورد دوم نادرست است. زیرا b به صورت keyword پاس داده شده است. مورد سوم نیز نادرست است زیرا e به صورت positional پاس داده شده است.کاربرد اصلی این ویژگی این است که می‌توان خوانایی برنامه‌ها را افزایش داد. مثلاً تابع len را می‌توان به صورت زیر تعریف کرد تا امکان پاس دادن مقدار به صورت keyword وجود نداشته باشد (زیرا باعث کاهش خوانایی می‌شود):def len(obj, /):
    # ...

len(obj=&amp;quotHello&amp;quot)  # Invalid. The &amp;quotobj&amp;quot keyword argument impairs readabilityهمچنین اگر پارامتری به این شکل تعریف شده باشد، بعداً می‌توان نام آن پارامتر را با خیال راحت تغییر داد. زیرا مطمئنیم که کدهایی که از تابع ما استفاده کرده‌اند، به نام پارامتر متکی نیستند.بسیاری جاها نیز پارامترهای keyword-only خوانایی را افزایش می‌دهند. مثلاً:def get_related_jobs(user, *, count=10, strict=False):
    # ...

get_related_jobs(user1, 50, True)  # Invalid. Not readable. What is 50? What is True?
get_related_jobs(user1, count=50, strict=True)  # Valid. More readable.نکته: نام پارامترهای positional-only همچنان می‌تواند در kwargs مورد استفاده قرار بگیرد:def counter(iterable, /, **kwargs):
    # ...

counter(mylist, a=1, iterable=2)  # Validتابع breakpoint (پایتون ۳٫۷)از پایتون ۳٫۷ به بعد برای دیباگ کردن بخشی از کد می‌توانید تابع جدید breakpoint را در آن‌جا صدا کنید و برنامه را اجرا کنید. به محض رسیدن برنامه به آن خط، شما به دیباگر پایتون (pdb) هدایت می‌شوید و می‌توانید به راحتی مقادیر متغیرها را درون shell آن بررسی کنید. در انتها نیز با اجرای دستور continue از pdb خارج می‌شوید و ادامۀ برنامه اجرا می‌شود.اگر یک توسعه‌دهندۀ Django هستید نیز می‌توانید از این تابع استفاده کنید و قبل از render شدن تمپلت، مقادیر متغیرها و queryset ها را درون shell بررسی کنید.قبل از پایتون ۳٫۷ نیز این امکان وجود داشت اما کدهای بیشتری لازم داشت. اکنون کافی‌است یک تابع ساده را صدا کنید.خوانایی بیشتر اعداد با _ (پایتون ۳٫۶)در پایتون ۳٫۶ می‌توانید برای خوانایی بیشتر اعداد، در میان ارقام آن کاراکتر _ قرار دهید.iran_surface = 1_648_195کلاس داده (Data Class) (پایتون ۳٫۷)در پایتون ۳٫۷ دکوراتوری به نام dataclass برای کلاس‌ها اضافه شده که تعدادی متد مانند سازنده (__init__)، متد __repr__، متد __eq__ و متد __hash__ را به صورت خودکار به کلاس اضافه می‌کند. به این ترتیب به سرعت و سادگی می‌توان یک کلاس برای نگهداری داده ایجاد کرد. مثال زیر را ببینید:from dataclasses import dataclass

@dataclass
class Point:
    x: float
    y: float
    z: float = 0.0

&gt;&gt;&gt; p = Point(1.5, 2.5)
&gt;&gt;&gt; print(p)
Point(x=1.5, y=2.5, z=0.0)
&gt;&gt;&gt; p2 = Point(1.5, 2.5, z=0)
&gt;&gt;&gt; p == p2
Trueماژول secrets (پایتون ۳٫۶)با این ماژول می‌توان به سادگی مقادیر شبه‌تصادفی که از لحاظ رمزنگاری قوی و امن هستند (به عبارت دیگر cryptographically strong هستند) برای کاربردهای امنیتی تولید کرد. نام این ماژول، به خوبی نمایانگر هدف آن است.یادآوری: برای کاربردهای امنیتی و رمزنگاری نباید از ماژول random برای تولید اعداد تصادفی استفاده کرد. مقادیری که توسط random تولید می‌شود برای کاربردهای امنیتی مناسب نیست. البته برعکس آن نیز صادق است. نیاز نیست برای تولید یک عدد تصادفی برای یک کاربرد ساده از ماژول secrets استفاده کرد، زیرا هزینۀ تولید عدد تصادفی با این ماژول بیشتر از ماژول random است.در مثال زیر نحوۀ تولید یک توکن ۱۶ بایتی با استفاده از secrets را می‌بینید:&gt;&gt;&gt; import secrets

&gt;&gt;&gt; secrets.token_bytes(16)
b&#039;\xebr\x17D*t\xae\xd4\xe3S\xb6\xe2\xebP1\x8b&#039;

&gt;&gt;&gt; secrets.token_hex(16)
&#039;f9bf78b9a18ce6d46a0cd2b0b86df9da&#039;امکانات دیگرامکانات مختلف دیگری در نسخه‌های جدید پایتون (مثلاً در ماژول typing) اضافه شده است که به علت طولانی شدن این مطلب به آن‌ها نپرداخته‌ام. برای آشنایی با آن‌ها، می‌توانید ارائه‌ای که منبع این مطلب بوده را ببینید:https://querateam.github.io/talks/presentations/New%20Python%20Features/یا این مطلب از وب‌سایت Real Python را مطالعه کنید:https://realpython.com/python38-new-features/یا مستندات پایتون (لینک‌های بخش منابع) را مطالعه کنید.منابعhttps://docs.python.org/3/whatsnew/3.8.htmlhttps://docs.python.org/3/whatsnew/3.7.htmlhttps://docs.python.org/3/whatsnew/3.6.htmlhttps://querateam.github.io/talks/presentations/New%20Python%20Features/</description>
                <category>Mohammad Javad Naderi</category>
                <author>Mohammad Javad Naderi</author>
                <pubDate>Fri, 20 Dec 2019 17:30:28 +0330</pubDate>
            </item>
                    <item>
                <title>پشتیبان‌گیری از داده‌ها: راه درست</title>
                <link>https://virgool.io/@mjnaderi/%D9%BE%D8%B4%D8%AA%DB%8C%D8%A8%D8%A7%D9%86%DA%AF%DB%8C%D8%B1%DB%8C-%D8%A7%D8%B2-%D8%AF%D8%A7%D8%AF%D9%87%D9%87%D8%A7-%D8%B1%D8%A7%D9%87-%D8%AF%D8%B1%D8%B3%D8%AA-jhn2mgtfpomc</link>
                <description>داده‌ها روی سخت‌افزار ذخیره می‌شوند و سخت‌افزار خراب می‌شود. فرقی نمی‌کند که یک رایانه‌ی شخصی کوچک باشد یا یک سرور گران‌قیمت در یک مرکز داده‌ی قدرتمند. هارد دیسک باشد یا SSD یا فلش. این یک واقعیت است: سخت‌افزار خراب می‌شود!از تابستان ۱۳۹۴ که توسعه‌ی Quera را شروع کردیم، پشتیبان‌گیری از داده‌ها برایمان یک دغدغه‌ی جدی بود. داده‌های مربوط به توسعه‌دهندگان، دانشگاه‌ها، مدارس و شرکت‌ها که برای ما و کاربران ارزش زیادی دارند و باید به خوبی از آن‌ها محافظت شود. به همین دلیل از همان اوایل از داده‌ها پشتیبان گرفتیم و تا به امروز سعی کرده‌ایم استراتژی پشتیبان‌گیری خود را بهبود دهیم.در این مدت حکایت‌های مختلفی از شرکت‌های مختلف در باب از دست رفتن داده‌ها شنیده‌ایم. وقتی بخشی از داده‌های یک شرکت از دست برود، سرنوشت به داده‌های پشتیبان بستگی دارد. آن روز می‌تواند با بازگرداندن داده‌ها از پشتیبان به خیر بگذرد؛ روزی که می‌توانست شکست کسب و کار را رقم بزند.یادم می‌آید روزی را که یکی از دوستان هارد دیسک سرور اصلی استارتاپشان را در دست داشت و به دنبال راهی برای بازگرداندن داده‌های آن بود. آن هارد دیسک دچار مشکل سخت‌افزاری شده بود و آخرین نسخه‌ی پشتیبان که از داده‌ها داشتند مربوط به چند ماه پیش بود... مدل کسب‌وکارشان طوری بود که حجم اعظم داده‌ها مجدداً قابل تولید بود و داده‌هایی که به ازای هر کاربر ذخیره می‌شد، چندان حیاتی نبود (گرچه مهم بود). به همین دلیل خوشبختانه توانستند هزینه‌ی این حادثه را تحمل کنند و کارشان را ادامه دهند.اما اگر چنین اتفاقی برای Quera بیفتد، فاجعه‌ای برای ما خواهد بود. اطلاعاتی از دست می‌رود که با زحمت هزاران نفر و صرف صدها هزار ساعت وقت به دست آمده (اطلاعات کلاس‌های درسی، تمرین‌های کلاسی و پاسخ‌های دانشجویان، هزاران سؤال برنامه‌نویسی و Test Case های آن‌ها، کدهای کاربران، اطلاعات شرکت‌ها و ...).استراتژی پشتیبان‌گیریپشتیبان‌گیری از داده برای هر کسب و کاری از مهم‌ترین ضروریات است. هر شرکت نیاز جدی به طراحی و مستندسازی یک استراتژی دقیق و مؤثر برای پشتیبان‌گیری از داده‌ها و بازیابی نسخه‌های پشتیبان دارد. پشتیبان‌گیری اگر به درستی انجام نشود، ممکن است خودش باعث خسارت شود!کمیک xkcd درباره استراتژی نادرست پشتیبان‌گیریفرض کنید در روز حادثه به سراغ داده‌های پشتیبان می‌روید و متوجه می‌شوید که ۳ ماه پیش دیسک سرور پشتیبان پر شده... یا این که متوجه می‌شوید داده‌های پشتیبان به قدری به‌روز هستند که داده‌های حذف‌شده از سرور اصلی، طی عملیات همگام‌سازی (Sync) از سرور پشتیبان نیز حذف شده‌اند! یا ممکن است حادثه‌ای رخ ندهد اما به دلیل تنظیمات ضعیف، سرور پشتیبان هک شود و داده‌ها لو برود.در این پست قصد ندارم همه‌ی استانداردهای لازم برای یک استراتژی مناسب را شرح دهم، زیرا مطلب بسیار مفصلی خواهد شد؛ به علاوه، من یک متخصص تمام‌عیار در این زمینه نیستم. تنها سعی می‌کنم بخشی از تجربیاتی که در این زمینه داشته‌ام را بیان کنم.روی بازیابی داده‌های حذف‌شده از دیسک حساب نکنیداحتمالاً پیش آمده که فایلی را اشتباهاً حذف کرده‌اید و با استفاده از نرم‌افزارهای بازیابی، آن را بازگردانده‌اید. اما وقتی صحبت از داده‌های یک سرور می‌شود، این روش بازیابی جواب نمی‌دهد، زیرا نیاز به بازگرداندن دقیق محتوا و نام هزاران فایل دارید. هیچ راه دررویی نیست! شما به داده‌ی پشتیبان نیاز دارید.از همه‌ی داده‌های حیاتی پشتیبان بگیریدبرخی داده‌ها مجدداً قابل تولید هستند و از دست دادن آن‌ها برایمان سنگین نیست. مثلاً اطلاعات جمع‌آوری‌شده از اینترنت توسط یک خزشگر (Crawler). اما بزرگترین بخش داده‌های شرکت‌ها، داده‌هایی هستند که نمی‌توانند مجدداً تولید شوند. مطمئن شوید که از همه‌ی داده‌های مهم پشتیبان تهیه می‌کنید. مثلاً پایگاه‌های داده، فایل‌های آپلودشده توسط کاربران، لاگ‌های مهم و هرچیزی که برایتان مهم است.مطمئن شوید که پشتیبان‌ها به سادگی قابل بازیابی هستندتصور کنید همین حالا حادثه‌ای برای سرور شما پیش بیاید و دیسک آن به کلی از بین برود. از خود بپرسید در چنین شرایطی چطور می‌توانید همه‌چیز را درست کنید؟ آیا کار سخت یا غیرممکنی خواهد بود؟ در این صورت باید استراتژی پشتیبان‌گیری خود را بازبینی کنید و مشکلاتش را برطرف کنید.مهم‌ترین نکته در پشتیبان‌گیری، قابل بازیابی بودن نسخه‌های پشتیبان است. خوب است مانور حادثه برگزار کنید. یک روز فرض کنید سرور اصلی شما به کلی از دست رفته است و سعی کنید تنها با استفاده از داده‌های پشتیبان یک نسخه از کسب‌وکارتان را راه‌اندازی کنید.در ۲ ژوئن ۲۰۱۶، سیستم پُلیگان وب‌سایت کدفرسز علیرغم پشتیبان‌گیری، داده‌های ۳ هفته‌ی خود را به خاطر یک نقص فنی از دست داد و نتوانست آن‌ها را بازیابی کند. توصیه می‌کنم داستانش را بخوانید.از داده‌ها در چند جا پشتیبان بگیریدداشتن تنها یک نسخه‌ی پشتیبان ریسک بالایی دارد. به ویژه اگر نسخه‌ی پشتیبان از لحاظ فیزیکی به داده‌های اصلی نزدیک باشد. فرض کنید مرکز داده دچار آتش‌سوزی یا حادثه‌ی دیگری شود. ممکن است داده‌های اصلی و نسخه‌ی پشتیبانی که در همان مرکز داده است با هم از بین بروند. باید چند نسخه از داده‌ها را در چند نقطه‌ی فیزیکی مختلف نگهداری کنید.پشتیبان‌گیری را به طور منظم و مداوم انجام دهیدپشتیبان‌گیری از داده‌ها را به صورت خودکار و منظم تنظیم کنید. برای هر بخش از داده‌ها بر اساس نرخ تغییرات آن و میزان حیاتی بودن آن تصمیم بگیرید که بازه‌ی زمانی برای پشتیبان‌گیری چقدر باشد. در لینوکس می‌توانید از Cron Job برای زمان‌بندی و خودکار کردن پشتیبان‌گیری استفاده کنید.پایش مداوم فرایند پشتیبان‌گیریخیلی خیلی مهم است که همواره از اجرای صحیح مراحل پشتیبان‌گیری مطمئن باشید. به طور مستمر پشتیبان‌ها را بررسی کنید تا در صورت بروز خطا به سرعت متوجه شوید. توصیه اکید می‌کنم که از سیستم‌های monitoring استفاده کنید و طوری تنظیم کنید که به محض بروز خطا شما را به طور خودکار مطلع کند. حواستان به فضای خالی و ظرفیت سرورها و دیسک‌های پشتیبان نیز باشد!پشتیبان‌ها را به صورت رمزنگاری‌شده ذخیره کنیدشما با پشتیبان‌گیری، داده‌های ارزشمند خود را در جاهای مختلف نگهداری می‌کنید و این کار، ریسک لو رفتن آن‌ها را افزایش می‌دهد. ممکن است یک هکر به دلیل سرمایه‌گذاری شما بر روی امنیت سرورهای اصلی، نتواند به آن‌ها نفوذ کند، اما بتواند به یکی از سرورهای پشتیبان شما نفوذ کند و داده‌ها را بخواند یا حتی تغییر دهد. بنابراین مهم است که داده‌های پشتیبان به صورت رمزنگاری‌شده ذخیره شوند تا این ریسک به حداقل برسد.پشتیبان‌گیری در Queraداده‌های حیاتی ما که از آن‌ها به طور منظم پشتیبان می‌گیریم در ۳ گروه زیر هستند:پایگاه داده‌ی PostgreSQLفایل‌ها، عمدتاً فایل‌های آپلودی کاربرانلاگ‌های مهمنحوه‌ی پشتیبان‌گیری ما از این داده‌ها به صورت اجمالی در ادامه می‌آید.لایه‌ی اول: پشتیبان‌گیری محلی از پایگاه دادهبا توجه به اهمیت پایگاه داده، به پشتیبان‌گیری از آن توجه ویژه‌ای کرده‌ایم. برای خودکار شدن فرایند و رسیدن به اهدافی که برایمان مهم بود، ابزار بسیار ساده‌ای به نام pgbackup توسعه دادیم که پشتیبان‌گیری از پایگاه داده را به صورت محلی (Local) و به دو روش Dump و PITR برایمان ساده‌تر می‌کند. این ابزار را در جایی منتشر نکرده‌ایم. پس اگر پروژه‌ای با همین نام پیدا کردید متعلق به ما نیست :)در روش اول یک بار در هر شبانه‌روز یک Dump از کل پایگاه داده گرفته و ذخیره می‌کنیم. نقش اصلی pgbackup در این مرحله، چرخش یا Rotation است، و نسخه‌های قدیمی را به نحوی حذف می‌کند که فایل‌های مربوط به ۷ روز اخیر به صورت روزانه، ۵ هفته‌ی اخیر به صورت هفتگی و ۱۲ ماه اخیر به صورت ماهانه باقی بمانند.گرفتن روزانه‌ی پشتیبان خوب است ولی در صورت بروز حادثه، در حالت میانگین اطلاعات ۱۲ ساعت از دست خواهد رفت. برای جلوگیری از این مشکل، از امکان PITR یا Point In Time Recovery پایگاه داده PostgreSQL استفاده می‌کنیم. این روش به صورت Incremental عمل می‌کند. به این صورت که ابتدا یک نسخه‌ی مبنا از پایگاه داده را ذخیره می‌کند و در طول زمان تک‌تک تغییرات پایگاه داده نسبت به پایگاه داده‌ی مبنا را در فایل‌هایی به نام WAL Archive ذخیره می‌کند. بنابراین شما یک پشتیبان پیوسته از پایگاه داده دارید و می‌توانید پایگاه داده را به هر لحظه‌ای از زمان که بخواهید برگردانید. مثلاً در صورتی که در ساعت ۱۲:۳۰ اطلاعات پایگاه داده حذف شود، کل پایگاه داده‌ی ساعت ۱۲:۲۹:۵۹ را دارید. بنابراین هیچ چیزی از دست نمی‌رود! زیبا نیست؟ :)این روش جادویی یک بار ما را نجات داده است. اشتباهاً کدی بر روی سرور اجرا شد که باعث حذف بخش کوچکی از پایگاه داده شد. به سرعت سایت را در حالت نگهداری قرار دادیم تا تغییر جدیدی روی پایگاه داده اتفاق نیفتد. سپس با استفاده از پشتیبان‌های PITR توانستیم پایگاه داده را به یک لحظه قبل از حادثه برگردانیم.به دلیل بالا بودن حجم WAL Archive ها، با استفاده از pgbackup پایگاه داده‌ی مبنا را هر هفته نوسازی می‌کنیم. البته پایگاه داده‌ی مبنا و  WAL Archive های هفته‌ی قبل را نیز نگهداری می‌کنیم. بنابراین برای ۷ تا ۱۴ روز (در حالت میانگین ۱۰ روز) پشتیبان PITR داریم و می‌توانیم پایگاه داده‌ی هر لحظه از ۱۰ روز گذشته را داشته باشیم.لایه‌ی دوم: پشتیبان‌گیری در خارج از سرورنوبت به این می‌رسد که از پشتیبان‌های محلی پایگاه داده، فایل‌ها و لاگ‌ها پشتیبان بگیریم. این کار را هر ۴ ساعت بر روی دو سرور در دو مرکز داده‌ی متفاوت انجام می‌دهیم.برای این که این پشتیبان‌ها به صورت رمزنگاری‌شده ذخیره شوند و کنترل مناسبی روی حذف نسخه‌های قدیمی داشته باشیم و همچنین برای این که حادثه‌ای که برای پُلیگان رخ داد برای ما اتفاق نیفتد، به جای استفاده از روش‌های ساده‌ای مانند rsync یا lsyncd از ابزار فوق‌العاده و متن‌باز Restic برای پشتیبان‌گیری استفاده می‌کنیم. Restic یک ابزار CLI متن‌باز برای پشتیبان‌گیری بهینه و امن است که به زبان Go نوشته شده است. این ابزار می‌تواند داده‌ها را بر روی سرور SFTP (با SSH)، سرور REST، سرویس S3 آمازون، سرویس ابری گوگل و ... ذخیره کند.لوگوی بامزه‌ی Restic!برای خودکارسازی فرایندها، یک نقش (Role) با Ansible ایجاد کردیم و این نقش را به دو سرور پشتیبانمان اختصاص دادیم. این نقش کارهای زیر را انجام می‌دهد:آماده‌سازی محیط پشتیبان‌گیری (یک بار): تنظیم دسترسی فایل‌ها، نصب Restic، تنظیمات SSH، ایجاد مخازن پشتیبانی، ایجاد Cron Jobعملیات پشتیبان‌گیری (هر ۴ ساعت): لاگ شروع پشتیبان‌گیری، پشتیبان‌گیری با Restic، لاگ پایان پشتیبان‌گیریحذف پشتیبان‌های قدیمی (هر ۲۴ ساعت): عملیات Forget و Prune در Resticیک مرحله جلوتر!اگر می‌خواهید استراتژی پشتیبان‌گیری کاملی داشته باشید و از دست نرفتن داده‌ها برایتان بسیار مهم است، به پشتیبان آفلاین نیز نیاز دارید. روی DVD، دیسک خارجی، فلش یا نوار مغناطیسی.این روزها که فناوری‌های جدید همه‌چیز را آنلاین کرده‌اند، این روش شاید کهنه و غیرضروری به نظر برسد. اما دعوت می‌کنم قبل از قضاوت حکایتی بخوانید از غول فناوری اطلاعات جهان، گوگل.در ۲۷ فوریه ۲۰۱۱، تیم پشتیبانی گوگل گزارش‌هایی را از کاربران جیمیل دریافت کرد که پس از ورود به حسابشان، با Inbox خالی مواجه شده بودند و تنظیماتشان به حالت اولیه بازگشته بود. تعدادی از کاربران نیز دریافت خطای ۵۰۰ سرور را گزارش داده بودند. مشخص شد که در نتیجه‌ی یک به‌روزرسانی نرم‌افزاری، دسترسی به اطلاعات ۴۰ هزار کاربر با مشکل رو به رو شده است. گوگل مجبور شد از پشتیبان‌های آفلاینی که روی نوارهای مغناطیسی ذخیره کرده بود برای بازگرداندن اطلاعات استفاده کند. گزارش گوگل از این حادثه را می‌توانید اینجا و اینجا بخوانید.پشتیبان آفلاین مزایایی دارد که نمی‌توان نادیده گرفت. اولین مزیت امنیت بالاتر داده‌هاست. داده‌های آنلاین همیشه در معرض خطر هکرها، باگ‌ها و آسیب‌پذیری‌های نرم‌افزاری هستند. ذخیره‌ی آفلاین داده‌ها به عنوان آخرین سد دفاعی، این ریسک را به حداقل می‌رساند.شرکت‌های بزرگ از نوار مغناطیسی به دلیل ظرفیت ذخیره‌سازی بالا و هزینه‌ی پایین برای پشتیبان آفلاین استفاده می‌کنند. اولین نوار مغناطیسی تجاری در سال ۱۹۵۱ بر روی رایانه‌ی یونیواک ۱ استفاده شد. امروز قادریم ده‌ها (و حتی صدها) ترابایت داده را روی تنها یک نوار مغناطیسی ذخیره کنیم.سمت راست: نوار مغناطیسی یونیسروو ۱، سال ۱۹۵۱   سمت چپ: یک کتابخانه‌ی نوار مغناطیسی (Tape Library) امروزینظر شما چیست؟ چه نکته‌ی مهمی را جا انداخته‌ام؟ شما هم از تجربیات خود در این زمینه بگویید.</description>
                <category>Mohammad Javad Naderi</category>
                <author>Mohammad Javad Naderi</author>
                <pubDate>Sun, 20 Oct 2019 12:20:40 +0330</pubDate>
            </item>
            </channel>
</rss>