PHP

2008-10-20 5 views
5

में एनएफएस फ़ाइलों को लॉक करना मेरे नवीनतम वेबपैप का हिस्सा इसकी लॉगिंग के हिस्से के रूप में उचित राशि दर्ज करने के लिए लिखने की आवश्यकता है। एक समस्या मैंने देखा है कि यदि कुछ समवर्ती उपयोगकर्ता हैं, तो लिख सकते हैं एक-दूसरे को ओवरराइट कर सकते हैं (फ़ाइल में शामिल होने के बजाय)। मुझे लगता है कि यह गंतव्य फ़ाइल की वजह से एक ही समय में कई स्थानों पर खुली जा सकती है।PHP

flock(...) आमतौर पर शानदार है लेकिन यह एनएफएस पर काम नहीं करता है ... जो मेरे लिए एक बड़ी समस्या है क्योंकि उत्पादन सर्वर एक एनएफएस सरणी का उपयोग करता है।

एक वास्तविक समाधान में मैंने जो सबसे नज़दीकी चीज देखी है, उसमें एक लॉक डायर बनाने और इसे बनाए जाने तक प्रतीक्षा करने का प्रयास करना शामिल है। कहने के लिए लालित्य की कमी वर्ष की कमी है, संभवतः दशक।

कोई बेहतर विचार?

संपादित करें: मुझे यह जोड़ना चाहिए कि मेरे पास सर्वर पर रूट नहीं है और किसी अन्य तरीके से स्टोरेज करना वास्तव में मेरे समय सीमा के भीतर कम से कम संभव नहीं है।

उत्तर

2

एक और गंदे हैक flock() एक "स्थानीय" फ़ाइल होगी, और यदि आप स्थानीय फ़ाइल पर लॉक रखते हैं तो केवल एनएफएस फ़ाइल को खोलें/लिखें।

संपादित करें: flock() पेज से:

झुंड() एनएफएस और कई अन्य नेटवर्क फाइल सिस्टम पर काम नहीं करेगा। अधिक जानकारी के लिए अपने ऑपरेटिंग सिस्टम दस्तावेज़ देखें।

संपादित करें 2:

बेशक वहाँ हमेशा डेटाबेस का उपयोग कर रहा है पहुँच synchonise करने के लिए (मैं अपने अनुप्रयोग संभालने कर रहा हूँ एक डाटाबेस का उपयोग करता है)। यदि आप बहुत सारे लॉगिंग कर रहे हैं तो यह काफी प्रदर्शन हिट होगा।

यदि यह सिर्फ लॉगिंग के लिए है, तो क्या आपको वास्तव में केंद्रीकृत लॉग फ़ाइल की आवश्यकता है? क्या आप स्थानीय रूप से लॉग इन कर सकते हैं (और यदि आवश्यक हो तो दिन के अंत में घूमते समय भी लॉग को गठबंधन करें)?

+0

फिलहाल, यह ठीक होगा, लेकिन एक बार यह विकास से बाहर हो जाने के बाद, इसे भार संतुलन के लिए कई वर्चुअल सर्वरों में फैलाया जा रहा है और यह कामों में एक [नाखून] स्पैनर फेंक देगा। – Oli

3

एक दृष्टिकोण Memcache उदाहरण स्थापित करने के लिए किया जा सकता है, जो आपके प्रत्येक वर्चुअल सर्वर के बीच साझा किया जाता है। जब आप स्थानीय फ़ाइल संचालन शुरू करते हैं, और समाप्त होने पर इसे पोंछते हैं तो आप फ़ाइल नाम की प्रविष्टि डालकर flock() एप कर सकते हैं।

प्रत्येक सर्वर फ़ाइल ऑपरेशन से पहले इस पूल तक पहुंच सकता है, और देख सकता है कि यह "लॉक" मौजूद है या नहीं।

// Check for lock, using $filename as key 
$lock = $memcache->get($filename); 

if(!$lock) { 
    // Set lock in memcache for $filename 
    $memcache->set($filename, 1); 

    // Do file operations... 

    // Blow away "lock" 
    $memcache->delete($filename); 
} 

नहीं समाधान के सबसे खूबसूरत है, लेकिन अपेक्षाकृत आसानी से अपने सेटअप में सभी सर्वरों से ताले को नियंत्रित करने के लिए सक्षम होना चाहिए।

0

केवल memcache जोड़ने और दौड़ की स्थिति से बचने के लिए उपयोग करना चाहिए। एनएफएस और मैं पर

if ($memcache->add($filename, 1, 1)) 
{ 
    $memcache->delete($filename); 
} 
1

भले ही आप झुंड नहीं कर सकते हैं() फ़ाइलें/ओ asynchroneous हो सकता है, एनएफएस पर निर्देशिका संचालन परमाणु कर रहे हैं। इसका मतलब है कि किसी भी समय, एक निर्देशिका करता है, या अस्तित्व में नहीं है।

अपनी खुद की एनएफएस लॉकिंग सुविधा को लागू करने के लिए, जब आप इसे लॉक करना चाहते हैं तो निर्देशिका को जांचें या बनाएं और इसे पूरा करने पर इसे हटा दें।

दुर्भाग्यवश, यह शायद किसी अन्य एप्लिकेशन के साथ संगत नहीं है जिसे आपने स्वयं नहीं लिखा था।

14

निर्देशिका संचालन हैं नहीं तहत NFSv2 और NFSv3 परमाणु (पुस्तक 'एनएफएस इलस्ट्रेटेड' ब्रेंट कैलहन द्वारा, ISBN 0-201-32570-5 का संदर्भ लें; ब्रेंट सूर्य पर एक एनएफएस-अनुभवी है)।

  • नाम बदलने
  • NFSv3 के साथ बनाने के कॉल भी परमाणु है

    • सिमलिंक:

      NFSv2 दो परमाणु कार्य किया है।

      यह जानकर, आप फ़ाइलों के लिए स्पिन ताले और निर्देशिका (शेल में, नहीं पीएचपी) को लागू कर सकते हैं:

      वर्तमान dir ताला:

      while ! ln -s ${f} ${f}.lock; do :; done 
      
      :

      while ! ln -s . lock; do :; done 
      

      एक फाइल ताला

      अनलॉक (धारणा, चल रही प्रक्रिया वास्तव में लॉक हासिल की गई):

      अनलॉक वर्तमान dir:

      mv lock deleteme && rm deleteme 
      

      अनलॉक एक फ़ाइल:

      mv ${f}.lock ${f}.deleteme && rm ${f}.deleteme 
      

      निकालें भी परमाणु नहीं है, इसलिए पहले नाम बदलने (जो परमाणु है) और फिर निकालें।

      सिम्लिंक के लिए और कॉल का नाम बदलने के लिए, दोनों फ़ाइल नामों को उसी फाइल सिस्टम पर रहना होगा। मेरा प्रस्ताव: केवल साधारण फ़ाइल नामों का उपयोग करें और फ़ाइल डालें और उसी निर्देशिका में लॉक करें।

    +0

    झुंड मैनुअल पेज पर ये टिप्पणियां संबंधित हैं और मैंने उन्हें काफी उपयोगी पाया। http://www.php.net/manual/en/function.flock.php#46085 http://www.php.net/manual/en/function.flock.php#68875 http: //www.php.net/manual/en/function.flock.php#82521 – aiham

    2

    आप एनएफएस वॉल्यूम पर फ़ाइलों को लॉक करने के लिए dio_fcntl() का भी उपयोग कर सकते हैं। इसे डीओओ पैकेज की आवश्यकता है, जो डिफ़ॉल्ट रूप से आपके PHP स्थापना का हिस्सा नहीं हो सकता है।