একটি ফোল্ডারে কয়েক মিলিয়ন (ছোট) পাঠ্য ফাইল


15

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

সর্বাধিক সোজা উপায় হ'ল ফোল্ডারে সমস্ত ফাইল সঞ্চয় করা:

$ ls text_files/
1.txt
2.txt
3.txt

যা কোনও EXT4 ফাইল সিস্টেমে সম্ভব হওয়া উচিত , যার কোনও ফোল্ডারে ফাইল সংখ্যার সীমা নেই।

দুটি এফএস প্রক্রিয়া হবে:

  1. ওয়েব স্ক্র্যাপ থেকে পাঠ্য ফাইলটি লিখুন (ফোল্ডারে ফাইল সংখ্যার দ্বারা প্রভাবিত হওয়া উচিত নয়)।
  2. ফাইলের নামের তালিকা দ্বারা প্রদত্ত ফাইলগুলি জিপ করুন।

আমার প্রশ্ন হ'ল, কোনও ফোল্ডারে দশ মিলিয়ন ফাইল সংরক্ষণের ফলে ফাইলগুলি বাস করার জন্য সাবফোল্ডার গাছ তৈরির পরিবর্তে উপরের ক্রিয়াকলাপ বা সাধারণ সিস্টেমের পারফরম্যান্সকে প্রভাব ফেলবে?


4
সম্পর্কিত: ডিভিতে যখন ডিভাইসে প্রচুর জায়গা থাকে তখন কীভাবে মধ্যবর্তী "ডিভাইসে কোনও স্থান অবশিষ্ট থাকবে না" ত্রুটিগুলি ঠিক করা যায় । ব্যবহার dir_index, যা প্রায়শই ডিফল্টরূপে সক্ষম হয়, তা অনুসন্ধানের গতি বাড়িয়ে দেবে তবে প্রতি ডিরেক্টরি ফাইলের সংখ্যা সীমিত করতে পারে।
মার্ক Plotnick

ভার্চুয়াল মেশিনে এটি কেন চেষ্টা করে দেখেন না এটি কেমন? বাশ দিয়ে অভ্যন্তরীণ এলোমেলো অক্ষরের সাথে মিলিয়ন পাঠ্য ফাইল সহ একটি ফোল্ডারকে পপুলেশন করা তুচ্ছ। আমার মনে হয় আপনি এখানে যা শিখবেন তা ছাড়াও আপনি সত্যিই দরকারী তথ্য পাবেন।
জোশুয়াডি

2
@ জোশুয়াড: আপনি যদি তা একবারে একটি তাজা এফএসে স্থাপন করেন, আপনার সম্ভবত ডিস্কে সমস্ত আইওনড সংবিধিবদ্ধ হওয়ার সম্ভাবনা রয়েছে, সুতরাং ls -lবা statডিরেক্টরিতে প্রতিটি bashইনোডের (যেমন গ্লোব্বিং / ট্যাব সমাপ্তি) অন্য যে কোনও কিছু কৃত্রিমভাবে দ্রুত হবে কিছু পরার পরে টিয়ার (কিছু ফাইল মুছুন, কিছু নতুন লিখুন)। এক্সএফএস এক্সএফএসের চেয়ে এটি আরও ভাল করতে পারে, কারণ এক্সএফএস ডায়নামিকভাবে আইওনড বনাম ডেটার জন্য স্থান বরাদ্দ করে, যাতে আপনি আরও ছড়িয়ে ছিটিয়ে থাকা ইনডগুলি দিয়ে শেষ করতে পারেন I (তবে এটি খুব কম বিশদ জ্ঞানের উপর ভিত্তি করে একটি খাঁটি অনুমান; আমি সবেমাত্র ext4 ব্যবহার করেছি)। abc/def/সাবদারদের সাথে যান ।
পিটার

হ্যাঁ, আমি মনে করি না যে আমি প্রস্তাবিত পরীক্ষাটি ওপিকে "এটি কাজ করবে" বলতে সক্ষম হবে, তবে এটি অবশ্যই তাকে দ্রুত "এটি কাজ করবে না" বলতে পারে, যা দরকারী is
জোশুয়াডি

1
তবে সম্মতি এবং সমান্তরালতার জন্য আমাদের প্রয়োজনীয়তা দেশীয় ফাইল সিস্টেমকে সেরা পছন্দটি ব্যবহার করে তোলে আপনি কী চেষ্টা করেছেন? অফহ্যান্ড, আমি এমনকি নীচের প্রান্তের আরডিবিএমএস যেমন মাইএসকিউএল এবং একটি জাভা সার্লেট সাথে ফ্লাইতে জিপ ফাইলগুলিZipOutputStream তৈরি করতে চাইলে যে কোনও ফ্রি লিনাক্স নেটিভ ফাইল সিস্টেমকে মারতে পারে - আমি সন্দেহ করি আপনি আইবিএমের জিপিএফএসের জন্য অর্থ দিতে চান doubt কোনও জেডিবিসি ফলাফল সেট প্রক্রিয়া করতে এবং সেই জিপ স্ট্রিমটি তৈরি করতে লুপটি সম্ভবত জাভা কোডের কেবল 6-8 লাইন।
অ্যান্ড্রু হেনেল

উত্তর:


10

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

আপনি যদি ট্যাব-সমাপ্তির তাগিদ প্রতিরোধ করতে পারেন এবং উদাহরণস্বরূপ জিপ করা ফাইলগুলির নাম সম্পূর্ণরূপে লিখতে পারেন তবে কোনও সমস্যা হবে না।

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

findকমান্ডটি ব্যবহার করে আপনার ওয়াইল্ডকার্ড অপারেশন করে এটি সমাধান করা যেতে পারে :

find <directory> -name '<wildcard expression>' -exec <command> {} \+

অথবা যখনই সম্ভব অনুরূপ বাক্য গঠন। find ... -exec ... \+স্বয়ংক্রিয়ভাবে একাউন্টে সর্বোচ্চ কমান্ড লাইন দৈর্ঘ্য নিতে হবে, এবং অনেক গুন বেশি কমান্ড চালানো হবে প্রয়োজনীয় সময় প্রতিটি কমান্ড লাইন থেকে ফাইলের সর্বোচ্চ পরিমাণ ঝুলানো।


আধুনিক ফাইল সিস্টেমগুলি ডিরেক্টরি এন্ট্রি রাখতে বি, বি + বা অনুরূপ গাছ ব্যবহার করে। en.wikipedia.org/wiki/HTree
DIMM

4
হ্যাঁ ... তবে শেল বা lsকমান্ডটি যদি না জানতে পারে যে ডিরেক্টরি তালিকাটি ইতিমধ্যে বাছাই করা হয়েছে তবে তারা যে কোনওভাবে বাছাই করা অ্যালগরিদম চালাতে সময় নিতে চলেছে। এবং তদ্ব্যতীত, ইউজারস্পেস স্থানীয়ভাবে বাছাই করা অর্ডার (LC_COLLATE) ব্যবহার করতে পারে যা ফাইল সিস্টেম অভ্যন্তরীণভাবে করতে পারে তার থেকে আলাদা হতে পারে।
telcoM

17

এটি বিপজ্জনকভাবে একটি মতামত ভিত্তিক প্রশ্ন / উত্তরের নিকটে তবে আমি আমার মতামত দিয়ে কিছু তথ্য সরবরাহ করার চেষ্টা করব।

  1. যদি আপনার একটি ফোল্ডারে ফাইলের সংখ্যা খুব বেশি থাকে তবে যে কোনও শেল-ভিত্তিক অপারেশন যা তাদের গণনা করার চেষ্টা করে (উদাহরণস্বরূপ mv * /somewhere/else) ওয়াইল্ডকার্ডটি সফলভাবে প্রসারিত করতে ব্যর্থ হতে পারে, বা ফলাফলটি ব্যবহার করতে খুব বড় হতে পারে।
  2. ls অল্প সংখ্যক ফাইলের চেয়ে খুব বড় সংখ্যক ফাইল গণনা করতে আরও সময় লাগবে।
  3. ফাইল সিস্টেমটি একক ডিরেক্টরিতে কয়েক মিলিয়ন ফাইল পরিচালনা করতে সক্ষম হবে, তবে লোকেরা সম্ভবত লড়াই করবে।

একটি সুপারিশ হ'ল ফাইল নামটি দুটি, তিন বা চারটি অক্ষরের অংশগুলিতে বিভক্ত করা এবং সেগুলি সাব-ডিরেক্টরি হিসাবে ব্যবহার করা। উদাহরণস্বরূপ, somefilename.txtহিসাবে সংরক্ষণ করা যেতে পারে som/efi/somefilename.txt। আপনি যদি সংখ্যার নাম ব্যবহার করে থাকেন তবে বাম থেকে ডানে পরিবর্তে ডান থেকে বামে বিভক্ত করুন যাতে আরও বেশি বিতরণ হয়। উদাহরণস্বরূপ 12345.txtহিসাবে সংরক্ষণ করা যেতে পারে 345/12/12345.txt

আপনি zip -j zipfile.zip path1/file1 path2/file2 ...জিপ ফাইলে অন্তর্বর্তী সাব-ডাইরেক্টরি পাথগুলি অন্তর্ভুক্ত করে এড়াতে আপনি এর সমতুল্য ব্যবহার করতে পারেন ।

যদি আপনি এই ওয়েবসাইভার থেকে এই ফাইলগুলি পরিবেশন করে থাকেন (তবে এটি প্রাসঙ্গিক কিনা তা আমি পুরোপুরি নিশ্চিত নই) Apache2 এ পুনর্লিখনের নিয়ম সহ ভার্চুয়াল ডিরেক্টরিটির পক্ষে এই কাঠামোটি লুকানো তুচ্ছ। আমি অনুমান করব যে একইভাবে Nginx এর ক্ষেত্রে সত্য।


*যদি না আপনি মেমরি ফুরিয়ে সম্প্রসারণ সফল হবে, কিন্তু যদি না আপনি (লিনাক্সের দিকে) stacksize সীমা বাড়াতে বা শেল যেখানে ব্যবহার mvbuiltin বা builtin হতে পারে (ksh93, zsh), execve()সিস্টেম কল একটি E2BIG ত্রুটি সহ বিফল হতে পারে।
স্টাফেন চেজেলাস

@ স্টাফেনচাজেলাস হ্যাঁ ঠিক আছে, আমার শব্দগুলির পছন্দটি আরও ভাল হতে পারে তবে ব্যবহারকারীর নেট প্রভাবটি একই রকম। জটিলতায় জড়িয়ে না গিয়ে আমি শব্দগুলি কিছুটা পরিবর্তন করতে পারি কিনা তা আমি দেখতে পাচ্ছি।
রোয়াইমা

আপনি কীভাবে জিপ ফাইলটিকে সংকুচিত করবেন তা আপনি কীভাবে জিজ্ঞাসাবাদ করবেন যে আপনি যদি এতে আলোচিত ইস্যুগুলি না চালিয়ে যদি এর মধ্যে অন্তর্বর্তী সাব-ডাইরেক্টরি পাথগুলি অন্তর্ভুক্ত না করেন তবে?
অক্টোপাস 21

1
@ অ্যাক্টপাস ওপিতে বলা হয়েছে যে জিপ ফাইলটিতে " নির্বাচিত ফাইলগুলি থাকবে, ফাইলের নামের সাথে দেওয়া "।
রোয়াইমা

আমি zip -j - ...সরাসরি ক্লায়েন্টের নেটওয়ার্ক সংযোগে আউটপুট স্ট্রিমটি ব্যবহার এবং পাইপ দেওয়ার পরামর্শ দেব zip -j zipfile.zip ...। ডিস্কে একটি আসল জিপফাইল লেখার অর্থ ডেটা পাথটি ডিস্ক থেকে> - কমপ্রেস-> ডিস্কে লিখুন-> ডিস্ক থেকে পড়ুন-> ক্লায়েন্টকে প্রেরণ করুন। যে পর্যন্ত করতে ট্রিপল আপনার ডিস্ক আই প্রয়োজনীয়তা উপর disk-> compress-> ক্লায়েন্ট পাঠাতে থেকে পড়া।
অ্যান্ড্রু হেনেল

5

আমি একটি ওয়েবসাইট চালনা করি যা চলচ্চিত্র, টিভি এবং ভিডিও গেমগুলির জন্য একটি ডাটাবেস পরিচালনা করে। এর প্রত্যেকটির জন্য টিভিতে একাধিক চিত্র রয়েছে যা প্রতি শোতে কয়েক ডজন চিত্র (যেমন পর্বের স্ন্যাপশট ইত্যাদি) ধারণ করে।

এখানে অনেকগুলি ফাইল ফাইল রয়েছে ends কোথাও 250,000+ সীমার মধ্যে। এগুলি সমস্ত মাউন্ট করা ব্লক স্টোরেজ ডিভাইসে সঞ্চিত থাকে যেখানে অ্যাক্সেসের সময় যুক্তিসঙ্গত হয়।

চিত্রগুলি সংরক্ষণ করার জন্য আমার প্রথম প্রচেষ্টাটি ছিল একক ফোল্ডারে /mnt/images/UUID.jpg

আমি নিম্নলিখিত চ্যালেঞ্জগুলি মধ্যে দৌড়ে।

  • lsএকটি রিমোট টার্মিনালের মাধ্যমে কেবল স্তব্ধ হয়ে যাবে। প্রক্রিয়া জম্বি হবে এবং CTRL+Cএটি ভঙ্গ করবে না।
  • আমি এই পর্যায়ে পৌঁছানোর আগে কোনও lsকমান্ড দ্রুত আউটপুট বাফারটি পূরণ করবে এবং CTRL+Cঅন্তহীন স্ক্রোলিং বন্ধ করবে না।
  • একক ফোল্ডার থেকে 250,000 ফাইল জিপ করতে প্রায় 2 ঘন্টা সময় নেয়। আপনাকে অবশ্যই টার্মিনাল থেকে বিচ্ছিন্ন জিপ কমান্ডটি চালাতে হবে অন্যথায় সংযোগে কোনও বাধা মানে আপনাকে আবার শুরু করতে হবে।
  • আমি উইন্ডোজে জিপ ফাইলটি ব্যবহার করার চেষ্টা করার ঝুঁকি নেব না।
  • ফোল্ডারটি দ্রুত কোনও মানুষের অনুমতিপ্রাপ্ত জোনে পরিণত হয়েছিল।

আমি পথটি তৈরির সময় সৃষ্টির সময়টি সাবফোল্ডারে ফাইলগুলি সঞ্চয় করে শেষ করেছি। যেমন /mnt/images/YYYY/MM/DD/UUID.jpg। এটি উপরের সমস্ত সমস্যা সমাধান করেছে এবং আমাকে জিপ ফাইলগুলি তৈরি করার অনুমতি দিয়েছে যা একটি তারিখকে লক্ষ্য করে।

যদি আপনার কাছে থাকা কোনও ফাইলের একমাত্র শনাক্তকারী একটি সংখ্যার সংখ্যা এবং এই সংখ্যাগুলি ক্রমান্বয়ে চলতে থাকে। কেন তাদের দ্বারা গ্রুপ না 100000, 10000এবং 1000

উদাহরণস্বরূপ, আপনার কাছে যদি নামে একটি ফাইল থাকে 384295.txtতবে পথটি হবে:

/mnt/file/300000/80000/4000/295.txt

যদি আপনি জানেন তবে আপনি কয়েক মিলিয়ন পৌঁছে যাবেন। 0১,০০,০০০ এর জন্য উপসর্গ ব্যবহার করুন

/mnt/file/000000/300000/80000/4000/295.txt

1

ওয়েব স্ক্র্যাপ থেকে পাঠ্য ফাইলটি লিখুন (ফোল্ডারে ফাইল সংখ্যার দ্বারা প্রভাবিত হওয়া উচিত নয়)।

একটি নতুন ফাইল তৈরি করতে ডিরেক্টরি ডিরেক্টরি স্ক্যান করা প্রয়োজন নতুন ডিরেক্টরি প্রবেশের জন্য পর্যাপ্ত ফাঁকা জায়গা সন্ধান করতে। নতুন ডিরেক্টরি এন্ট্রি সংরক্ষণের জন্য যথেষ্ট পরিমাণে কোনও স্থান না থাকলে এটি ডিরেক্টরি ফাইলের শেষে স্থাপন করা হবে। ডিরেক্টরিতে ফাইলের সংখ্যা বাড়ার সাথে সাথে ডিরেক্টরি স্ক্যান করার সময়ও বৃদ্ধি পায়।

ডিরেক্টরি ফাইলগুলি যতক্ষণ সিস্টেম ক্যাশে থাকে, ততক্ষণ এ থেকে সম্পাদনাটি কার্যকর হবে না, তবে ডেটা প্রকাশ করা হলে ডিরেক্টরি থেকে ফাইল ফাইল (সাধারণত অত্যন্ত খণ্ডিত) পড়া বেশ কিছুটা সময় ব্যয় করতে পারে। একটি এসএসডি এটিকে উন্নত করে, তবে কয়েক মিলিয়ন ফাইল সহ ডিরেক্টরিতে এখনও লক্ষণীয় পারফরম্যান্স হিট হতে পারে।

ফাইলের নামের তালিকা দ্বারা প্রদত্ত ফাইলগুলি জিপ করুন।

লক্ষ লক্ষ ফাইল সহ ডিরেক্টরিতে এটি অতিরিক্ত সময়ের প্রয়োজন হতে পারে। হ্যাশ ডিরেক্টরি ডিরেক্টরি (যেমন EXT4) সহ একটি ফাইল-সিস্টেমে, এই পার্থক্যটি ন্যূনতম।

কোনও ফোল্ডারে দশ মিলিয়ন ফাইল সংরক্ষণ করে উপরের ক্রিয়াকলাপের উপর প্রভাব ফেলবে বা সাধারণ সিস্টেমের পারফরম্যান্স, ফাইলগুলি বাস করার জন্য সাবফোল্ডার গাছ তৈরির চেয়ে আলাদা কি অন্যরকম?

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


1

প্রথমত: 'ls' কে 'ls -U' দিয়ে বাছাই করতে বাধা দিন, সম্ভবত আপনার alias / bashrc আপডেট করুন 'ওরফে ls = "ls -U"' বা এর অনুরূপ থাকতে।

আপনার বড় ফাইলসেটের জন্য, আপনি এটি এর মতো করে দেখতে পারেন:

  • পরীক্ষার ফাইলগুলির একটি সেট তৈরি করুন

  • দেখুন অনেকগুলি ফাইলের নাম সমস্যার কারণে রয়েছে কিনা

  • সমস্যাগুলি এড়ানোর জন্য xargs পারমিটার-ব্যাচিং এবং জিপ-এর ফাইলগুলি একটি জিপ-এ যুক্ত করার আচরণ (ডিফল্ট) ব্যবহার করুন।

এটি ভাল কাজ করেছে:

# create ~ 100k files
seq 1 99999 | sed "s/\(.*\)/a_somewhat_long_filename_as_a_prefix_to_exercise_zip_parameter_processing_\1.txt/" | xargs touch
# see if zip can handle such a list of names
zip -q /tmp/bar.zip ./*
    bash: /usr/bin/zip: Argument list too long
# use xargs to batch sets of filenames to zip
find . -type f | xargs zip -q /tmp/foo.zip
l /tmp/foo.zip
    28692 -rw-r--r-- 1 jmullee jmullee 29377592 2017-12-16 20:12 /tmp/foo.zip
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.