针对已存储文件的数百万个哈希检查数百万个文件

时间:2014-01-31 11:29:54

标签: mysql database hash memcached bigdata

我有一个拥有数百万sha256哈希文件的数据库。 我经常收到数以百万计的新文件,我必须检查数据库以避免重复。

根据mysql数据库检查文件的哈希需要数年时间。我已经将哈希分成了16个表(0到F)。我已经尝试过couchbase,但是这需要超过8GB的内存并且导致数百万次哈希导致大量内存使用导致导入...

任何人都可以给我一个解决方案来存储大约4,5GB的哈希值(当哈希值被转储到纯文本文件时大小减去),这个数据库比MySQL快吗?

存储哈希时没有任何元信息,没有文件名或路径或id或whatelse。

亲切的问候, 3vilc00kie

编辑表格定义:

-- phpMyAdmin SQL Dump
-- version 3.3.9
-- http://www.phpmyadmin.net
--
-- Host: 127.0.0.1
-- Erstellungszeit: 31. Januar 2014 um 13:55
-- Server Version: 5.5.8
-- PHP-Version: 5.3.5

SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO";


/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;

--
-- Datenbank: `filehashes`
--

-- --------------------------------------------------------

--
-- Tabellenstruktur für Tabelle `0`
--

CREATE TABLE IF NOT EXISTS `0` (
  `sha256` binary(32) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

-- --------------------------------------------------------

--
-- Tabellenstruktur für Tabelle `1`
--

CREATE TABLE IF NOT EXISTS `1` (
  `sha256` binary(32) NOT NULL,
  UNIQUE KEY `sha256` (`sha256`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

-- --------------------------------------------------------

--
-- Tabellenstruktur für Tabelle `2`
--

CREATE TABLE IF NOT EXISTS `2` (
  `sha256` binary(32) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

-- --------------------------------------------------------

--
-- Tabellenstruktur für Tabelle `3`
--

CREATE TABLE IF NOT EXISTS `3` (
  `sha256` binary(32) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

-- --------------------------------------------------------

--
-- Tabellenstruktur für Tabelle `4`
--

CREATE TABLE IF NOT EXISTS `4` (
  `sha256` binary(32) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

-- --------------------------------------------------------

--
-- Tabellenstruktur für Tabelle `5`
--

CREATE TABLE IF NOT EXISTS `5` (
  `sha256` binary(32) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

-- --------------------------------------------------------

--
-- Tabellenstruktur für Tabelle `6`
--

CREATE TABLE IF NOT EXISTS `6` (
  `sha256` binary(32) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

-- --------------------------------------------------------

--
-- Tabellenstruktur für Tabelle `7`
--

CREATE TABLE IF NOT EXISTS `7` (
  `sha256` binary(32) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

-- --------------------------------------------------------

--
-- Tabellenstruktur für Tabelle `8`
--

CREATE TABLE IF NOT EXISTS `8` (
  `sha256` binary(32) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

-- --------------------------------------------------------

--
-- Tabellenstruktur für Tabelle `9`
--

CREATE TABLE IF NOT EXISTS `9` (
  `sha256` binary(32) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

-- --------------------------------------------------------

--
-- Tabellenstruktur für Tabelle `a`
--

CREATE TABLE IF NOT EXISTS `a` (
  `sha256` binary(32) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

-- --------------------------------------------------------

--
-- Tabellenstruktur für Tabelle `b`
--

CREATE TABLE IF NOT EXISTS `b` (
  `sha256` binary(32) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

-- --------------------------------------------------------

--
-- Tabellenstruktur für Tabelle `c`
--

CREATE TABLE IF NOT EXISTS `c` (
  `sha256` binary(32) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

-- --------------------------------------------------------

--
-- Tabellenstruktur für Tabelle `d`
--

CREATE TABLE IF NOT EXISTS `d` (
  `sha256` binary(32) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

-- --------------------------------------------------------

--
-- Tabellenstruktur für Tabelle `e`
--

CREATE TABLE IF NOT EXISTS `e` (
  `sha256` binary(32) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

-- --------------------------------------------------------

--
-- Tabellenstruktur für Tabelle `f`
--

CREATE TABLE IF NOT EXISTS `f` (
  `sha256` binary(32) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

5 个答案:

答案 0 :(得分:6)

您可能不需要数据库。

sha256只有32个字节长。我生成了一个包含5000万个唯一sha256的列表,对它们进行排序,然后将它们放在一个文件中(不用十六进制编码)。这是1.5GB的RAM,用于非常均衡的二进制排序结构。对于你能找到的任何计算机而言,这应该很容易。

所以你要做的就是读取或mmap它,并为你检查的每一个做二进制搜索。

当sha1s的LinkedIn数据库泄露时,有一个网站尝试通过将所有哈希值放在数据库服务器中并让用户从Web请求中检查它们来尝试做与此类似的操作。

它不能可靠地工作,所以我基本上构建了上面描述的内容。如果你在我的要点中获取代码:https://gist.github.com/dustin/2885182并修改sha256(基本上将散列大小设置为32而不是20),它应该可以很好地工作。您可以使用文件扫描程序内联逻辑运行,以进行大约即时查找。

答案 1 :(得分:2)

只需在'sha256'字段中添加索引即可。实际上,正如Dustin指出的那样,这只是1.5 GB的数据。它将适合MySQL中的单个表,如果这是你感到满意的(你显然是)。只是索引。

答案 2 :(得分:1)

我会使用MySQL分区,而不是处理多个表。您可以非常轻松地将数据分区为多个表以及索引。这简化了查询和维护。

但是,以下是重要的。在mdx哈希上创建索引 - 这不必是主键或唯一索引。如果你正确地做了事情,那么索引将是加载到内存中的唯一东西。

其次,确保MySQL配置为使用大量内存。

如果索引适合内存,那么你没问题。

获取“数百万个新文件”的过程表明在比较方面进行了优化。如果“文件”在应用程序中并且您要逐个进行比较,则在进行比较之前,通过哈希 排序文件。按顺序遍历数据将为性能带来奇迹。

如果它们在数据库中,则将它们放在以哈希作为主键的临时表中。这将保持秩序。然后索引查找将非常有效,即使索引不完全适合内存。

答案 3 :(得分:0)

您可以使用MySQL:

答案 4 :(得分:0)

我认为在您的情况下,您应该使用 HBASE Redis

您可以使用HBASE或 Cassandra 来存储文件。

由于文件的大小和散列是使用MySQL的GB,因此不是更好的选择。

您可以使用 Redis 来存储文件的哈希值。

我有机会使用Redis,根据我的经验,我可以说Redis非常快。 原因是, REDIS是一个内存数据存储。

This可能有助于了解有关redis的更多信息。

所以,我认为你应该使用

HBASE / CASSANDRA:数据存储

REDIS:用于存储哈希。

希望这可能有所帮助。 感谢。