我有一个拥有数百万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;
答案 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:
探索在哈希上使用UNIQUE
约束的自动增量主键,而不是使用哈希作为主键。使用相当大的数据集对此进行基准测试,以了解这是否有帮助。
如果使用innodb,请将innodb_buffer_pool_size
配置设置为可用内存的50-80%:http://docs.oracle.com/cd/E17952_01/refman-5.5-en/innodb-configuration.html
如果您不想知道重复项是什么,请使用REPLACE INTO ... VALUES (hash1), (hash2), ...
在一个语句中一次插入4000或10000个哈希值。试验大块插入物应该有多大以达到良好的性能平衡。
答案 4 :(得分:0)
我认为在您的情况下,您应该使用 HBASE 和 Redis 。
您可以使用HBASE或 Cassandra 来存储文件。
由于文件的大小和散列是使用MySQL的GB,因此不是更好的选择。
您可以使用 Redis 来存储文件的哈希值。
我有机会使用Redis,根据我的经验,我可以说Redis非常快。 原因是, REDIS是一个内存数据存储。
This可能有助于了解有关redis的更多信息。
所以,我认为你应该使用
HBASE / CASSANDRA:数据存储
REDIS:用于存储哈希。
希望这可能有所帮助。 感谢。