起因
昨日微信群里有人詢問技術(shù)問題,忙里偷閑回了兩句,閑下來后感覺指的的路有點兒歪。深覺惶恐,顧整理一下思路,希望能減少一些謬誤。為了行文需要,沒有完全拘泥于群里的原始問題,有故意跑偏意圖。
友情提示:本文看一半覺得有理,一定是被帶坑里了;如果堅持看完,還能引發(fā)更多批評和思考,說明幸免于難 :)
問題
前端計算大文件MD5有啥高效的辦法嗎?
加載800m文件計算太慢了,放后端計算就要先上傳上去。
方案0:按需求,直接解。
百度一把,發(fā)現(xiàn) spark-md5.js,號稱全宇宙最快的前端類包,可以無需上傳文件就快速獲取本地文件md5……
document.getElementById('file').addEventListener('change', function () {
var blobSlice = File.prototype.slice || File.prototype.mozSlice || File.prototype.webkitSlice,
file = this.files[0],
chunkSize = 2097152, // Read in chunks of 2MB
chunks = Math.ceil(file.size / chunkSize),
currentChunk = 0,
spark = new SparkMD5.ArrayBuffer(),
fileReader = new FileReader();
fileReader.onload = function (e) {
console.log('read chunk nr', currentChunk + 1, 'of', chunks);
spark.append(e.target.result); // Append array buffer
currentChunk++;
if (currentChunk < chunks) {
loadNext();
} else {
console.log('finished loading');
console.info('computed hash', spark.end()); // Compute hash
}
};
fileReader.onerror = function () {
console.warn('oops, something went wrong.');
};
function loadNext() {
var start = currentChunk * chunkSize,
end = ((start + chunkSize) >= file.size) ? file.size : start + chunkSize;
fileReader.readAsArrayBuffer(blobSlice.call(file, start, end));
}
loadNext();
});
方案1:加入限制維度
在想不清楚時,先參考行業(yè)標(biāo)桿做法,后續(xù)再慢慢理解其為什么要這么做。

方案2:加入用戶體驗維度
再高的計算性能都架不住數(shù)據(jù)量的挑戰(zhàn),更無法阻止用戶心中的怒火。
思路是,先忽略內(nèi)部實現(xiàn),從用戶視角,分析出能接受的時間限制,然后再思考解決方案。
在這個案例中,讓客戶等不現(xiàn)實,就需要從算法上下手。需求是如何算MD5,但本質(zhì)是判重。
可選的方案是,抽取文件的某些片段來生成特征值,再加上文件大小等信息,可解決大部分重復(fù)文件的判定;代價是有誤判的風(fēng)險,補充方案是,上傳后再依據(jù)一定條件再決定是否做完整的MD5值計算。優(yōu)點的是客戶體驗好,缺點是系統(tǒng)架構(gòu)復(fù)雜度增加。
足夠了嗎?等等……
方案3:靠近業(yè)務(wù),尋找進(jìn)一步優(yōu)化的機會
前面3種方案的共性是,沒有充分利用視頻這類數(shù)據(jù)的專用維度,而是實際解決的是通用的文件判重。優(yōu)點是獲取了一定的通用性,缺點是錯過了更接地氣的方案。視頻數(shù)據(jù)都有其固定格式的,研究一下,從視頻文件角度,收集更多元數(shù)據(jù)信息參與判重計算,從而進(jìn)一步計算算力??梢詤⒖?a target="_blank" rel="nofollow">擴展閱讀2,可獲得很多靈感。
方案4:我們真的理解需求了嗎?
產(chǎn)品提的需求是視頻判重。問題是,怎么判定兩個視頻重復(fù)呢?判定標(biāo)準(zhǔn)是什么?以全文算MD5,是錯1位都會認(rèn)為不重復(fù),這樣會導(dǎo)致人覺得重復(fù),而機器認(rèn)為不一樣。
回到需求,其實是想避免重復(fù)的內(nèi)容被上傳。人判定是否重復(fù)并不是對比MD5值是否一致,而是通過模糊對比而給出結(jié)果。于是需要和需求方確認(rèn)更多細(xì)節(jié):
1、視頻格式不同,內(nèi)容一致,是否認(rèn)為重復(fù)?
2、視頻清晰度不同,內(nèi)容一致,是否認(rèn)為重復(fù)?
3、視頻被剪輯摘錄,是否認(rèn)為重復(fù)?多少重復(fù)才認(rèn)為為重復(fù)?
4、……
OK?還差一步
我們設(shè)計出一個好的方案,于是信心滿滿的去找產(chǎn)品人員溝通。慢!
以理服人?NO!
產(chǎn)品提需求時,或多或少都會做一些調(diào)研工作。研發(fā)如直接否決需求,僅希望通過講道理,是很難達(dá)成共識的。所以改變思路,即基于數(shù)據(jù)溝通。
研發(fā)人員PK產(chǎn)品人員,多數(shù)都是失敗的故事。如果雙方不是對比誰更牛,而是共同面對事實、面對數(shù)據(jù),聚焦在問題上,則很容易達(dá)成共識。
具體方案:提前用數(shù)據(jù)度量要解決的問題,量化估算方案的效果,包括:
1、設(shè)計的算法有多少準(zhǔn)確率?
2、對于客戶的價值是什么?
3、對于后臺系統(tǒng)的影響有多大?節(jié)省了多少成本。
4、……
擴展閱讀
- spark-md5 http://npm.taobao.org/package/spark-md5
- OceanBase 2.0的高級數(shù)據(jù)壓縮特性 https://mp.weixin.qq.com/s/TId97PKIGB7OL5QjIkLLrg