Redis
 sql >> डेटाबेस >  >> NoSQL >> Redis

Redis/php-resque का उपयोग करके समवर्ती ImageMagick अनुरोधों का अनुकूलन

आपका आदेश वास्तव में इस पर उबलता है:

convert -size 600x400 xc:none                                 \
    \( 1.png -fill rgb\(x,y,z\) -colorize 100% \) -composite  \
    \( 2.png -fill rgb\(x,y,z\) -colorize 100% \) -composite  \
    \( 3.png -fill rgb\(x,y,z\) -colorize 100% \) -composite  \
    \( 4.png -fill rgb\(x,y,z\) -colorize 100% \) -composite  \
    \( 5.png -fill rgb\(x,y,z\) -colorize 100% \) -composite  \
    \( 6.png -fill rgb\(x,y,z\) -colorize 100% \) -composite  \
    result.png

मेरे विचार इस प्रकार हैं:

प्वाइंट 1:

पहला -composite एक खाली कैनवास पर व्यर्थ लगता है - संभवतः 1.png पारदर्शिता के साथ एक 600x400 पीएनजी है, इसलिए आपकी पहली पंक्ति कंपोजिटिंग ऑपरेशन से बच सकती है और 16% प्रोसेसिंग समय को इसमें बदलकर बचा सकती है:

convert -background none 1.png -fill ... -colorize 100% \
   \( 2.png ..
   \( 3.png ...

प्वाइंट 2

मैंने आपके आदेश के बराबर एक लूप में रखा और 100 पुनरावृत्तियों को किया और इसमें 15 सेकंड लगते हैं। इसके बाद मैंने आपकी सभी पीएनजी फाइलों को MPC . के रीड्स में बदल दिया फ़ाइलें - या Magick पिक्सेल कैश फ़ाइलें। इसने प्रसंस्करण समय को केवल 10 सेकंड से कम, यानी 33% तक कम कर दिया। मैजिक पिक्सेल कैश सिर्फ एक प्री-डिकंप्रेस्ड, प्री-डिकोडेड फाइल है जिसे बिना किसी सीपीयू प्रयास के सीधे मेमोरी में पढ़ा जा सकता है। जब भी आपका कैटलॉग बदलता है तो आप उन्हें प्री-क्रिएट कर सकते हैं और उन्हें पीएनजी फाइलों के साथ स्टोर कर सकते हैं। एक बनाने के लिए आप करते हैं

convert image.png image.mpc

और आपको image.mpc मिल जाएगा और image.cache . तब आप बस इस तरह दिखने के लिए अपना कोड बदल देंगे:

convert -size 600x400 xc:none                                 \
    \( 1.mpc -fill rgb\(x,y,z\) -colorize 100% \) -composite  \
    \( 2.mpc -fill rgb\(x,y,z\) -colorize 100% \) -composite  \
    \( 3.mpc -fill rgb\(x,y,z\) -colorize 100% \) -composite  \
    \( 4.mpc -fill rgb\(x,y,z\) -colorize 100% \) -composite  \
    \( 5.mpc -fill rgb\(x,y,z\) -colorize 100% \) -composite  \
    \( 6.mpc -fill rgb\(x,y,z\) -colorize 100% \) -composite  \
    result.png

प्वाइंट 3

दुर्भाग्य से आपने अभी तक मेरे सवालों का जवाब नहीं दिया है, लेकिन अगर आपकी संपत्ति सूची बहुत बड़ी नहीं है, तो आप सिस्टम स्टार्टअप पर रैम डिस्क पर (या ऊपर एमपीसी समकक्ष) डाल सकते हैं।

प्वाइंट 4

आपको निश्चित रूप से समानांतर में दौड़ना चाहिए - इससे सबसे बड़ा लाभ मिलेगा। जीएनयू समानांतर के साथ यह बहुत आसान है - उदाहरण यहां।

यदि आप रेडिस का उपयोग कर रहे हैं, तो यह वास्तव में उससे कहीं अधिक आसान है। बस LPUSH आपकी MIME-एन्कोडेड छवियों को इस तरह एक REDIS सूची में:

#!/usr/bin/perl
################################################################################
# generator.pl <number of images> <image size in bytes>
# Mark Setchell
# Base64 encodes and sends "images" of specified size to REDIS
################################################################################
use strict;
use warnings FATAL => 'all';
use Redis;
use MIME::Base64;
use Time::HiRes qw(time);

my $Debug=0;    # set to 1 for debug messages

my $nargs = $#ARGV + 1;
if ($nargs != 2) {
    print "Usage: generator.pl <number of images> <image size in bytes>\n";
    exit 1;
}

my $nimages=$ARGV[0];
my $imsize=$ARGV[1];

# Our "image"
my $image="x"x$imsize;

printf "DEBUG($$): images: $nimages, size: $imsize\n" if $Debug;

# Connection to REDIS
my $redis = Redis->new;
my $start=time;

for(my $i=0;$i<$nimages;$i++){
   my $encoded=encode_base64($image,'');
   $redis->rpush('images'=>$encoded);
   print "DEBUG($$): Sending image $i\n" if $Debug;
}
my $elapsed=time-$start;
printf "DEBUG($$): Sent $nimages images of $imsize bytes in %.3f seconds, %d images/s\n",$elapsed,int($nimages/$elapsed);

और फिर कई कर्मचारियों को चलाते हैं जो सभी वहां बैठकर काम करने के लिए बीएलपीओपी करते हैं

#!/usr/bin/perl
################################################################################
# worker.pl
# Mark Setchell
# Reads "images" from REDIS and uudecodes them as fast as possible
################################################################################
use strict;
use warnings FATAL => 'all';
use Redis;
use MIME::Base64;
use Time::HiRes qw(time);

my $Debug=0;    # set to 1 for debug messages
my $timeout=1;  # number of seconds to wait for an image
my $i=0;

# Connection to REDIS
my $redis = Redis->new;

my $start=time;

while(1){
   #my $encoded=encode_base64($image,'');
   my (undef,$encoded)=$redis->blpop('images',$timeout);
   last if !defined $encoded;
   my $image=decode_base64($encoded);
   my $l=length($image);
   $i++; 
   print "DEBUG($$): Received image:$i, $l bytes\n" if $Debug;
}

my $elapsed=time-$start-$timeout; # since we waited that long for the last one
printf "DEBUG($$): Received $i images in %.3f seconds, %d images/s\n",$elapsed,int($i/$elapsed);

अगर मैं ऊपर की तरह एक जनरेटर प्रक्रिया चलाता हूं और यह 200kB प्रत्येक की 100,000 छवियां उत्पन्न करता है, और उन्हें मेरे उचित विनिर्देश iMac पर 4 कार्यकर्ता प्रक्रियाओं के साथ पढ़ता है, तो इसमें 59 सेकंड लगते हैं, या लगभग 1,700 छवियां REDIS से गुजर सकती हैं।

  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. रेडिस इंस्टेंस संस्करण की जांच कैसे करें?

  2. पाइथन का उपयोग करके रेडिस में कॉम्प्लेक्स नेस्टेड JSON को कैसे स्टोर करें

  3. रेडिस की एक्सपायरी कुंजी कैसे होती है?

  4. रेडिस में सम्मिलित कुंजी प्राप्त करें

  5. क्या रेडिस केवल स्ट्रिंग प्रतिनिधित्व की अनुमति देता है लेकिन संख्यात्मक मान नहीं