Стратегия генерации ключей Memcache - PullRequest
2 голосов
/ 15 апреля 2010

Учитывая функцию f1 , которая получает n строковых аргументов, что было бы лучше с точки зрения производительности во время выполнения, стратегии генерации случайного ключа для memcache?

Наш клиент Memcache выполняет внутреннее хеширование md5sum для получаемых ключей:

   public class MemcacheClient {  
       public Object get(String key) {
            String md5 = Md5sum.md5(key)
            // Talk to memcached to get the Serialization... 
            return memcached(md5);
       }
   }

Мои сценарии использования:

Первый вариант

    public static String f1(String s1, String s2, String s3, String s4) {
         String key = s1 +  s2 + s3 + s4;
         return get(key);
    }

Второй вариант

    /**
     * Calculate hash from Strings
     *
     * @param objects vararg list of String's
     *
     * @return calculated md5sum hash
     */
    public static String stringHash(Object... strings) {
        if(strings == null) 
            throw new NullPointerException("D'oh! Can't calculate hash for null");

        MD5 md5sum = new MD5();

//      if(prevHash != null)
//          md5sum.Update(prevHash);

        for(int i = 0; i < strings.length; i++) {
            if(strings[i] != null) {
                md5sum.Update("_"); 
                md5sum.Update(strings[i].toString()); // Convert to String...
                md5sum.Update("_");

            } else {
                // If object is null, allow minimum entropy  by hashing it's position
                md5sum.Update("_");
                md5sum.Update(i);
                md5sum.Update("_");
            }
        }

        return md5sum.asHex();
    }


    public static String f1(String s1, String s2, String s3, String s4) {
         String key = stringHash(s1, s2, s3, s4);
         return get(key);
    }

Обратите внимание, что возможная проблема со вторым вариантом заключается в том, что мы выполняем второй md5sum (в клиенте memcache) для уже обработанного результата дайджеста md5sum.

Спасибо за чтение, Максим.

- Правка Используется служебный источник MD5

Ответы [ 2 ]

1 голос
/ 15 апреля 2010

Просто придирки, но вы, вероятно, не хотите случайное генерирование ключа, генерация ключа должна быть детерминированная , но должна генерировать равномерное распределение в клавиша пробела.

Если вы рассматриваете только случайные столкновения, то первый подход почти подходит. Вы должны префиксировать строки с их длиной, чтобы не возникало коллизий при перемещении подстроки из одного параметра в другой. Учитывая довольно хорошие лавинные свойства md5, которые гарантируют, что случайные столкновения достаточно редки, чтобы их игнорировать.

Но будьте осторожны с MD5, если вы обрабатываете пользовательский ввод, он знает о столкновениях. Если ненадежный пользователь может выбрать несколько произвольных байтов для параметров функции, и возвращение неверного результата может иметь последствия для безопасности, тогда у вас есть дыра в безопасности. Например, если вы используете это для кэширования информации авторизации, злоумышленник может обработать два набора параметров, которые хэшируют одно значение. Один будет иметь доступ к чему-то общедоступному, а другой - к защищенному сервису. Теперь просто запросите авторизацию с первым набором, получите кэширование авторизации и затем получите доступ к защищенному сервису с другим набором, получив зеленый свет от кэшированной авторизации.

1 голос
/ 15 апреля 2010

«Лучше» в каком смысле? Почему вы думаете, что второй вариант "лучше"? Он выполняет больше конкатенаций строк, больше хэшей MD5 и, как правило, кажется гораздо менее эффективным, чем первый ...

...