BigData: HBase

বিদ্যমান

6.1 এইচবেস কে এবং কেন আবিষ্কার করেন

এই বক্তৃতায়, আমরা Hbase এর মতো একটি দুর্দান্ত সরঞ্জাম সম্পর্কে কথা বলব, যা সম্প্রতি দুর্দান্ত জনপ্রিয়তা অর্জন করেছে: উদাহরণস্বরূপ, Facebook এটিকে তার মেসেজিং সিস্টেমের ভিত্তি হিসাবে ব্যবহার করে এবং এটি ইতিমধ্যে অনেক কিছু বলে।

বক্তৃতাটি বিগ টেবিলের ধারণা এবং এর বিনামূল্যে বাস্তবায়ন, কাজের বৈশিষ্ট্য এবং উভয় ক্লাসিক্যাল রিলেশনাল ডাটাবেস (যেমন মাইএসকিউএল এবং ওরাকল) এবং রেডিস, অ্যারোস্পাইক এবং মেমক্যাচেডের মতো মূল-মূল্যের স্টোরেজ থেকে পার্থক্য সম্পর্কে কথা বলবে। যথারীতি, ইস্যুটির ইতিহাস দিয়ে শুরু করা যাক। অন্যান্য অনেক BigData প্রকল্পের মতো, Hbase একটি ধারণা থেকে জন্ম নিয়েছে যা Google দ্বারা তৈরি করা হয়েছিল। Hbase এর পিছনের নীতিগুলি Bigtable : A Distributed Storage System for Structured Data নিবন্ধে বর্ণিত হয়েছে ।

যেমনটি আমরা পূর্ববর্তী লেকচারে আলোচনা করেছি, সাধারণ ফাইলগুলি MapReduce প্যারাডাইম ব্যবহার করে ব্যাচ ডেটা প্রসেসিংয়ের জন্য বেশ উপযুক্ত। অন্যদিকে, ফাইলগুলিতে সংরক্ষিত তথ্য আপডেট করা বরং অসুবিধাজনক; ফাইলগুলি এলোমেলো অ্যাক্সেসের সম্ভাবনা থেকেও বঞ্চিত হয়। এলোমেলো অ্যাক্সেস সহ দ্রুত এবং সুবিধাজনক কাজের জন্য, একটি শ্রেণির nosql সিস্টেম রয়েছে যেমন কী-মানের স্টোরেজ, যেমন Aerospike, Redis, Couchbase, Memcached। যাইহোক, ব্যাচ প্রক্রিয়াকরণ সাধারণত এই সিস্টেমে খুব অসুবিধাজনক হয়. Hbase আপডেট এবং এলোমেলো অ্যাক্সেসের সুবিধার সাথে ব্যাচ প্রক্রিয়াকরণের সুবিধার সমন্বয় করার একটি প্রচেষ্টা।

6.2 ডেটা মডেল

HBase হল একটি বিতরণ করা, কলাম-ভিত্তিক, মাল্টিভারসন কী-ভ্যালু ডাটাবেস।

  • ডেটা Hbase-এ RowKey নামক একটি প্রাথমিক কী দ্বারা সূচীকৃত টেবিলে সংগঠিত হয়।
  • প্রতিটি RowKey কী-এর জন্য, গুণাবলীর (বা কলাম) একটি সীমাহীন সেট সংরক্ষণ করা যেতে পারে।
  • কলামগুলি কলামের গ্রুপে সংগঠিত হয় যাকে বলা হয় কলাম পরিবার। একটি নিয়ম হিসাবে, একই ব্যবহার এবং স্টোরেজ প্যাটার্ন আছে এমন কলামগুলিকে একটি কলাম পরিবারে একত্রিত করা হয়।
  • প্রতিটি বৈশিষ্ট্যের জন্য, বিভিন্ন সংস্করণ সংরক্ষণ করা যেতে পারে। বিভিন্ন সংস্করণের বিভিন্ন টাইমস্ট্যাম্প আছে।

রেকর্ডগুলি শারীরিকভাবে RowKey সাজানো ক্রমে সংরক্ষণ করা হয়। এই ক্ষেত্রে, বিভিন্ন কলাম পরিবারের সাথে সম্পর্কিত ডেটা আলাদাভাবে সংরক্ষণ করা হয়, যা প্রয়োজনে শুধুমাত্র পছন্দসই কলাম পরিবার থেকে ডেটা পড়ার অনুমতি দেয়।

যখন একটি নির্দিষ্ট বৈশিষ্ট্য মুছে ফেলা হয়, এটি অবিলম্বে শারীরিকভাবে মুছে ফেলা হয় না, তবে শুধুমাত্র একটি বিশেষ সমাধির পাথরের পতাকা দিয়ে চিহ্নিত করা হয়। মেজর কমপ্যাকশন অপারেশন সঞ্চালিত হলে ডেটার ফিজিক্যাল ডিলিট পরে ঘটবে।

একই কলাম গোষ্ঠীর অন্তর্গত এবং একই কী এর সাথে সম্পর্কিত বৈশিষ্ট্যগুলি একটি সাজানো তালিকা হিসাবে শারীরিকভাবে সংরক্ষণ করা হয়। প্রতিটি কীর জন্য যেকোন বৈশিষ্ট্য অনুপস্থিত বা উপস্থিত হতে পারে এবং যদি বৈশিষ্ট্যটি অনুপস্থিত থাকে তবে এটি খালি মান সংরক্ষণের ওভারহেডের কারণ হয় না।

তালিকা এবং কলাম গোষ্ঠীর নামগুলি স্থির করা হয়েছে এবং একটি পরিষ্কার বিন্যাস রয়েছে৷ কলাম গ্রুপ লেভেলে, টাইম টু লাইভ (TTL) এবং সর্বোচ্চ সংখ্যক সংরক্ষিত সংস্করণের মতো প্যারামিটার সেট করা হয়। যদি একটি নির্দিষ্ট সংস্করণের টাইমস্ট্যাম্প এবং বর্তমান সময়ের মধ্যে পার্থক্য TTL-এর চেয়ে বেশি হয়, তাহলে এন্ট্রিটি মুছে ফেলার জন্য চিহ্নিত করা হয়। যদি একটি নির্দিষ্ট বৈশিষ্ট্যের সংস্করণের সংখ্যা সর্বাধিক সংস্করণের সংখ্যা অতিক্রম করে, তবে রেকর্ডটি মুছে ফেলার জন্যও চিহ্নিত করা হয়।

Hbase ডেটা মডেলটিকে একটি মূল-মান মিল হিসাবে মনে রাখা যেতে পারে:

<table, RowKey, Column Family, Column, timestamp> -> Value

6.3 সমর্থিত অপারেশন

hbase-এ সমর্থিত ক্রিয়াকলাপগুলির তালিকাটি বেশ সহজ। 4টি প্রধান অপারেশন সমর্থিত:

  • রাখুন : hbase এ একটি নতুন এন্ট্রি যোগ করুন। এই এন্ট্রির টাইমস্ট্যাম্প হাতে সেট করা যেতে পারে, অন্যথায় এটি বর্তমান সময়ে স্বয়ংক্রিয়ভাবে সেট করা হবে।
  • পান : একটি নির্দিষ্ট RowKey-এর জন্য ডেটা পান। আপনি কলাম পরিবার নির্দিষ্ট করতে পারেন যেখান থেকে আমরা ডেটা নেব এবং আমরা যে সংস্করণ পড়তে চাই তার সংখ্যা।
  • স্ক্যান : একের পর এক রেকর্ড পড়ুন। আপনি যে রেকর্ড থেকে আমরা পড়া শুরু করি, যে রেকর্ডে পড়তে হবে, রেকর্ডের সংখ্যা, যে কলাম পরিবার থেকে পড়া হবে এবং প্রতিটি রেকর্ডের জন্য সর্বাধিক সংখ্যক সংস্করণ উল্লেখ করতে পারেন।
  • মুছুন : মুছে ফেলার জন্য একটি নির্দিষ্ট সংস্করণ চিহ্নিত করুন। কোন শারীরিক মুছে ফেলা হবে না, এটি পরবর্তী মেজর কমপ্যাকশন পর্যন্ত স্থগিত করা হবে (নীচে দেখুন)।

6.4 স্থাপত্য

HBase হল একটি ডিস্ট্রিবিউটেড ডাটাবেস যা কয়েক ডজন বা শত শত ফিজিক্যাল সার্ভারে চলতে পারে, তাদের মধ্যে কিছু ব্যর্থ হলেও নিরবচ্ছিন্ন অপারেশন নিশ্চিত করে। অতএব, ক্লাসিক রিলেশনাল ডাটাবেসের তুলনায় HBase-এর আর্কিটেকচার বেশ জটিল।

HBase তার কাজের জন্য দুটি প্রধান প্রক্রিয়া ব্যবহার করে:

1. অঞ্চল সার্ভার - এক বা একাধিক অঞ্চল পরিবেশন করে। একটি অঞ্চল হল রেকর্ডের একটি পরিসর যা ধারাবাহিক রোকিগুলির একটি নির্দিষ্ট পরিসরের সাথে সম্পর্কিত। প্রতিটি অঞ্চলে রয়েছে:

  • স্থায়ী স্টোরেজ হল HBase-এর প্রধান ডেটা স্টোরেজ। ডেটা শারীরিকভাবে HDFS-এ একটি বিশেষ HFile বিন্যাসে সংরক্ষণ করা হয়। HFile-এ ডেটা RowKey সাজানো ক্রমে সংরক্ষণ করা হয়। এক জোড়া (অঞ্চল, কলাম পরিবার) অন্তত একটি HFIle এর সাথে মিলে যায়।
  • মেমস্টোর - বাফার লিখুন। যেহেতু ডেটা HFile d-এ সাজানো ক্রমে সংরক্ষণ করা হয়, তাই রেকর্ড প্রতি HFile আপডেট করা বেশ ব্যয়বহুল। পরিবর্তে, লেখার সময়, ডেটা একটি বিশেষ মেমস্টোর মেমরি এলাকায় প্রবেশ করে, যেখানে এটি কিছু সময়ের জন্য জমা হয়। যখন MemStore কিছু গুরুত্বপূর্ণ মান পূরণ করা হয়, ডেটা একটি নতুন HFile এ লেখা হয়।
  • ব্লকক্যাশ - পড়ার জন্য ক্যাশে। আপনাকে ঘন ঘন পঠিত ডেটাতে উল্লেখযোগ্যভাবে সময় বাঁচাতে দেয়।
  • এহেড লগ (WAL) লিখুন । যেহেতু ডাটা মেমস্টোরে লেখা হয়, তাই ক্র্যাশের কারণে ডাটা নষ্ট হওয়ার কিছু ঝুঁকি থাকে। এটি যাতে না ঘটে তার জন্য, ম্যানিপুলেশনের প্রকৃত বাস্তবায়নের আগে সমস্ত ক্রিয়াকলাপ একটি বিশেষ লগ ফাইলে পড়ে। এটি আপনাকে কোনও ব্যর্থতার পরে ডেটা পুনরুদ্ধার করতে দেয়।

2. মাস্টার সার্ভার - HBase ক্লাস্টারের প্রধান সার্ভার। মাস্টার অঞ্চল সার্ভারগুলির মধ্যে অঞ্চলগুলির বন্টন পরিচালনা করে, অঞ্চলগুলির একটি রেজিস্টার বজায় রাখে, নিয়মিত কাজগুলি চালু করা পরিচালনা করে এবং অন্যান্য দরকারী কাজগুলি করে৷

পরিষেবাগুলির মধ্যে ক্রিয়াগুলি সমন্বয় করতে, HBase Apache ZooKeeper ব্যবহার করে, একটি বিশেষ পরিষেবা যা কনফিগারেশনগুলি পরিচালনা করতে এবং পরিষেবাগুলিকে সিঙ্ক্রোনাইজ করার জন্য ডিজাইন করা হয়েছে৷

যখন অঞ্চলে ডেটার পরিমাণ বৃদ্ধি পায় এবং এটি একটি নির্দিষ্ট আকারে পৌঁছায়, তখন Hbase বিভক্ত হতে শুরু করে, একটি ক্রিয়াকলাপ যা অঞ্চলটিকে 2 দ্বারা বিভক্ত করে। অঞ্চলগুলির অবিচ্ছিন্ন বিভাজন এড়াতে, আপনি অঞ্চলগুলির সীমানা আগে থেকেই সেট করতে পারেন এবং তাদের সর্বাধিক বৃদ্ধি করতে পারেন আকার

যেহেতু একটি অঞ্চলের জন্য ডেটা বেশ কয়েকটি HFiles-এ সংরক্ষণ করা যেতে পারে, তাই Hbase কাজের গতি বাড়ানোর জন্য পর্যায়ক্রমে সেগুলিকে একত্রিত করে। এই অপারেশনকে Hbase-এ কমপ্যাকশন বলা হয়। কম্প্যাকশন দুই ধরনের হয়:

  • ক্ষুদ্র কম্প্যাকশন । স্বয়ংক্রিয়ভাবে শুরু হয়, ব্যাকগ্রাউন্ডে চলে। অন্যান্য Hbase অপারেশনের তুলনায় কম অগ্রাধিকার আছে।
  • প্রধান কম্প্যাকশন । এটি হাতে বা নির্দিষ্ট ট্রিগারের সংঘটনের উপর চালু করা হয় (উদাহরণস্বরূপ, একটি টাইমার দ্বারা)। এটির একটি উচ্চ অগ্রাধিকার রয়েছে এবং এটি ক্লাস্টারটিকে উল্লেখযোগ্যভাবে ধীর করতে পারে। যখন ক্লাস্টারে লোড কম থাকে তখন মেজর কম্প্যাকশনগুলি সর্বোত্তমভাবে করা হয়। মেজর কমপ্যাকশনও শারীরিকভাবে পূর্বে সমাধির পাথর দিয়ে চিহ্নিত ডেটা মুছে দেয়।

6.5 HBase এর সাথে কাজ করার উপায়

HBase শেল

Hbase দিয়ে শুরু করার সবচেয়ে সহজ উপায় হল hbase শেল ইউটিলিটি ব্যবহার করা। যেকোন hbase ক্লাস্টার নোডে hbase ইনস্টল করার সাথে সাথে এটি পাওয়া যায়।

Hbase শেল হল একটি জরুবি কনসোল যা সমস্ত মৌলিক Hbase অপারেশনের জন্য অন্তর্নির্মিত সমর্থন সহ। নিম্নলিখিত দুটি কলাম পরিবারগুলির সাথে একটি ব্যবহারকারীর টেবিল তৈরি করার একটি উদাহরণ, এটিতে কিছু ম্যানিপুলেশন করা এবং টেবিলটি hbase শেলের শেষে ফেলে দেওয়া:

create 'users', {NAME => 'user_profile', VERSIONS => 5}, {NAME => 'user_posts', VERSIONS => 1231231231} 
put 'users', 'id1', 'user_profile:name', 'alexander' 
put 'users', 'id1', 'user_profile:second_name', 'alexander' 
get 'users', 'id1' 
put 'users', 'id1', 'user_profile:second_name', 'kuznetsov' 
get 'users', 'id1' 
get 'users', 'id1', {COLUMN => 'user_profile:second_name', VERSIONS => 5} 
put 'users', 'id2', 'user_profile:name', 'vasiliy' 
put 'users', 'id2', 'user_profile:second_name', 'ivanov' 
scan 'users', {COLUMN => 'user_profile:second_name', VERSIONS => 5} 
delete 'users', 'id1', 'user_profile:second_name' 
get 'users', 'id1' 
disable 'users' 
drop 'users'

নেটিভ API

অন্যান্য হ্যাডুপ-সম্পর্কিত প্রকল্পগুলির মতো, hbase জাভাতে প্রয়োগ করা হয়, তাই জাভাতে নেটিভ এপিআই পাওয়া যায়। নেটিভ API অফিসিয়াল ওয়েবসাইটে বেশ ভালভাবে নথিভুক্ত করা হয়েছে। সেখান থেকে নেওয়া Hbase API ব্যবহার করার একটি উদাহরণ এখানে দেওয়া হল:

import java.io.IOException;

import org.apache.hadoop.hbase.*;
import org.apache.hadoop.hbase.client.*;
import org.apache.hadoop.hbase.util.Bytes;

public class MyLittleHBaseClient {
  public static void main(String[] args) throws IOException {
	Configuration config = HBaseConfiguration.create();
	Connection connection = ConnectionFactory.createConnection(config);
	try {
  	Table table = connection.getTable(TableName.valueOf("myLittleHBaseTable"));
  	try {
    	Put p = new Put(Bytes.toBytes("myLittleRow"));
    	p.add(Bytes.toBytes("myLittleFamily"), Bytes.toBytes("someQualifier"),
    	Bytes.toBytes("Some Value"));
    	table.put(p);

    	Get g = new Get(Bytes.toBytes("myLittleRow"));
    	Result r = table.get(g);
    	byte [] value = r.getValue(Bytes.toBytes("myLittleFamily"),
      	Bytes.toBytes("someQualifier"));

    	String valueStr = Bytes.toString(value);
    	System.out.println("GET: " + valueStr);

    	Scan s = new Scan();
    	s.addColumn(Bytes.toBytes("myLittleFamily"), Bytes.toBytes("someQualifier"));
    	ResultScanner scanner = table.getScanner(s);
    	try {
       	for (Result rr = scanner.next(); rr != null; rr = scanner.next()) {
         	System.out.println("Found row: " + rr);
       	}
     	} finally {
       	scanner.close();
     	}
   	} finally {
     	if (table != null) table.close();
   	}
 	} finally {
   	connection.close();
 	}
  }
}

অন্যান্য প্রোগ্রামিং ভাষার জন্য থ্রিফ্ট, REST এবং সমর্থন

অন্যান্য প্রোগ্রামিং ভাষা থেকে কাজ করার জন্য, Hbase Thrift API এবং Rest API প্রদান করে। তাদের উপর ভিত্তি করে, ক্লায়েন্টগুলি সমস্ত প্রধান প্রোগ্রামিং ভাষার জন্য তৈরি করা হয়: পাইথন, পিএইচপি, জাভা স্ক্রিপ্ট ইত্যাদি।

6.6 HBase এর সাথে কাজ করার কিছু বৈশিষ্ট্য

  1. Hbase MapReduce এর সাথে বাক্সের বাইরে একীভূত হয় এবং বিশেষ TableInputFormat এবং TableOutputFormat ব্যবহার করে ইনপুট এবং আউটপুট হিসাবে ব্যবহার করা যেতে পারে।

  2. সঠিক RowKey নির্বাচন করা খুবই গুরুত্বপূর্ণ। RowKey-কে অবশ্যই অঞ্চল জুড়ে একটি ভাল সমান বন্টন প্রদান করতে হবে, অন্যথায় তথাকথিত "গরম অঞ্চল" হওয়ার ঝুঁকি রয়েছে - যে অঞ্চলগুলি অন্যদের তুলনায় অনেক বেশি ব্যবহৃত হয়, যা সিস্টেম সংস্থানগুলির অদক্ষ ব্যবহারের দিকে পরিচালিত করে।

  3. যদি ডেটা এককভাবে আপলোড করা না হয়, তবে অবিলম্বে বড় ব্যাচে, Hbase একটি বিশেষ বাল্কলোড প্রক্রিয়া সমর্থন করে যা আপনাকে একক পুট ব্যবহার করার চেয়ে অনেক দ্রুত ডেটা আপলোড করতে দেয়। বাল্কলোড মূলত একটি দ্বি-পদক্ষেপ অপারেশন:

    • একটি বিশেষ MapReduce কাজ ব্যবহার করে পুটের অংশগ্রহণ ছাড়াই HFile গঠন
    • এই ফাইলগুলি সরাসরি Hbase এ সন্নিবেশ করা হচ্ছে
  4. Hbase Ganglia মনিটরিং সার্ভারে তার মেট্রিক্স আউটপুট সমর্থন করে। Hbase সমস্যাগুলির নীচে যাওয়ার জন্য Hbase পরিচালনা করার সময় এটি খুব সহায়ক হতে পারে।

সারি কী

RowKey হল ইউজার আইডি, যা একটি GUUID, একটি স্ট্রিং যা বিশ্বব্যাপী অনন্য হওয়ার জন্য বিশেষভাবে তৈরি করা হয়। GUUID গুলি সমানভাবে বিতরণ করা হয়, যা সার্ভার জুড়ে ডেটার একটি ভাল বিতরণ দেয়।

কলাম পরিবার

আমাদের স্টোরেজ দুটি কলাম পরিবার ব্যবহার করে:

  • তথ্য কলামগুলির এই গোষ্ঠীটি এমন ডেটা সঞ্চয় করে যা বিজ্ঞাপনের উদ্দেশ্যে আর প্রাসঙ্গিক নয়, যেমন কোনও ব্যবহারকারী নির্দিষ্ট URL গুলি পরিদর্শন করেছে৷ এই কলাম পরিবারের জন্য TTL 2 মাসের জন্য সেট করা হয়েছে, সংস্করণের সংখ্যা 2000।
  • দীর্ঘ তথ্য কলামের এই গোষ্ঠীটি ডেটা সঞ্চয় করে যা সময়ের সাথে তার প্রাসঙ্গিকতা হারায় না, যেমন লিঙ্গ, জন্ম তারিখ এবং অন্যান্য "অনন্ত" ব্যবহারকারীর বৈশিষ্ট্য।

স্পিকার

প্রতিটি ধরনের ব্যবহারকারীর তথ্য একটি পৃথক কলামে সংরক্ষণ করা হয়। উদাহরণস্বরূপ, Data:_v কলাম ব্যবহারকারী দ্বারা পরিদর্শন করা URL গুলি সংরক্ষণ করে এবং LongData:gender কলাম ব্যবহারকারীর লিঙ্গ সংরক্ষণ করে৷

এই সত্যের সময় স্ট্যাম্প একটি টাইমস্ট্যাম্প হিসাবে সংরক্ষণ করা হয়. উদাহরণ স্বরূপ, Data:_v কলামে, টাইমস্ট্যাম্প হল ব্যবহারকারীর একটি নির্দিষ্ট URL দেখার সময়।

এই ব্যবহারকারীর ডেটা স্টোরেজ কাঠামোটি আমাদের ব্যবহারের প্যাটার্নের সাথে খুব ভালভাবে ফিট করে এবং আপনাকে ব্যবহারকারীর ডেটা দ্রুত আপডেট করতে, ব্যবহারকারীদের সম্পর্কে সমস্ত প্রয়োজনীয় তথ্য দ্রুত পেতে এবং, MapReduce ব্যবহার করে, একসাথে সমস্ত ব্যবহারকারীর ডেটা দ্রুত প্রক্রিয়া করার অনুমতি দেয়।

6.7 বিকল্প

HBase পরিচালনা এবং ব্যবহার করার জন্য বেশ জটিল, তাই HBase ব্যবহার করার আগে বিকল্পগুলি দেখতে বোঝা যায়:

  • রিলেশনাল ডাটাবেস । একটি খুব ভাল বিকল্প, বিশেষ করে ক্ষেত্রে যখন ডেটা একটি মেশিনে ফিট হয়। এছাড়াও, প্রথমত, প্রাথমিক ব্যতীত অন্য সূচীগুলির লেনদেন গুরুত্বপূর্ণ হলে আপনার রিলেশনাল ডেটাবেস সম্পর্কে চিন্তা করা উচিত।

  • মূল-মূল্য সঞ্চয়স্থান । রেডিস এবং অ্যারোস্পাইকের মতো স্টোরেজগুলি যখন বিলম্বের প্রয়োজন হয় এবং ব্যাচ প্রক্রিয়াকরণ কম গুরুত্বপূর্ণ হয় তখন আরও উপযুক্ত।

  • MapReduce এর সাথে ফাইল এবং তাদের প্রক্রিয়াকরণ । যদি ডেটা শুধুমাত্র যোগ করা হয় এবং খুব কমই আপডেট/পরিবর্তিত হয়, তাহলে HBase ব্যবহার না করাই ভালো, কিন্তু ফাইলগুলিতে ডেটা সংরক্ষণ করুন। ফাইলগুলির সাথে কাজটি সহজ করার জন্য, আপনি Hive, Pig এবং Impala এর মতো সরঞ্জামগুলি ব্যবহার করতে পারেন।

HBase এর ব্যবহার যুক্তিযুক্ত যখন:

  • প্রচুর ডেটা রয়েছে এবং সেগুলি এক কম্পিউটার/সার্ভারে ফিট হয় না
  • ডেটা প্রায়শই আপডেট এবং মুছে ফেলা হয়
  • ডেটাতে একটি সুস্পষ্ট "কী" রয়েছে, যার সাথে অন্য সবকিছু আবদ্ধ করা সুবিধাজনক
  • ব্যাচ প্রক্রিয়াকরণ প্রয়োজন
  • নির্দিষ্ট কী দ্বারা ডেটাতে র্যান্ডম অ্যাক্সেস প্রয়োজন
মন্তব্য
  • জনপ্রিয়
  • নতুন
  • পুরানো
মন্তব্য লেখার জন্য তোমাকে অবশ্যই সাইন ইন করতে হবে
এই পাতায় এখনও কোনো মন্তব্য নেই