久久国产精品一区二区三区四区,久色婷婷小香蕉久久,国产日韩欧美在线播放不卡,另类av一区二区

今亮點!短鏈系統設計(design tiny url)
來源:JavaEdge    時間:2022-09-13 18:52:14
短鏈系統設計(design tiny url)

如脈脈,不會縱容你發太長的網址,會給你轉成短鏈。

1.Scenario 場景

根據一個 long url 生成一個short url。


(資料圖)

如 http://www.javaedge.com => http://bit.ly/1ULoQB6

根據 short url 還原 long url,并跳轉:

需和面試官確認的問題:

long url和short url必須一一對應嗎?

Short url長時間沒人用,需要釋放嗎?

1.1 QPS 分析問日活,如微博100M推算產生一條 tiny url 的 qps

假設每個用戶平均每天 0.1(發10 條,有一條有鏈接) 條帶 URL 的微博

平均寫 QPS = 100M * 0.1 / 86400 = 100

峰值寫 qps = 100 * 2 = 200

推算點擊一條tiny url的 qps

假設每個用戶平均點 1 個tiny url

平均寫 QPS = 100M * 1 / 86400 = 1k

峰值讀 qps = 1k * 2 = 2k

deduce 每天產生的新 URL 所占存儲

100M * 0.1 = 10M 條

每條 URL 長度平均按 100 算,共 1G

1T 硬盤能用 3 年

由2、3 分析可知,并不需要分布式或者 sharding,支持 2k QPS,一臺 SSD MySQL 即可。

2.Service 服務 - 邏輯塊聚類與接口設計

該系統其實很簡單,只需要有一個 service即可:URL Service。由于 tiny url只有一個 UrlService:

本身其實就是個小的獨立應用也無需關心其他任何業務功能

方法設計:

UrlService.encode(long_url):編碼方法

UrlService.decode(long_url):解碼方法

訪問端口設計,當前有如下兩種常用主流風格:

GET /REST 風格Return a http redirect resonseREST 風格Return a http redirect resonsePOST /data/shorten(不太推薦,不符合 REST 設計風格,但也有人在用) returh a short url

那么,你們公司的短鏈系統是選擇哪種服務設計呢?

3.Storage 數據存?。ㄗ钅荏w現實踐經驗)select 選存儲結構scheme 細化數據表3.1 SQL V.S NoSQL

需要事務嗎?No,nosql+1

需要豐富的 sql query 嗎?no,nosql+1

想偷懶嗎?tiny url需要寫的代碼不復雜,nosql+1

qps高嗎?2k,不高。sql+1

scalability 要求多高?存儲和 qps 都不高,單機都能搞定。sql+1

- sql 需要自己寫代碼來 scale- nosql,這些都幫你做了

是否需要 sequential ID?取決于你的算法

sql 提供 auto_increment 的 sequencetial ID,即 1,2,3nosql 的 ID 不是 sequential3.2 算法

long ur 轉成一個 6 位的 short url。給出一個長網址,返回一個短網址。

實現兩個方法:

longToShort(url)?把一個長網址轉換成一個以http://tiny.url/開頭的短網址shortToLong(url)把一個短網址轉換成一個長網址shortToLong(url)把一個短網址轉換成一個長網址

標準:

短網址的key的長度應為6 (不算域名和反斜杠)??捎米址挥衃a-zA-Z0-9]?. 比如:abcD9E[a-zA-Z0-9]?. 比如:abcD9E任意兩個長的url不會對應成同一個短url,反之亦然。

用兩個哈希表:

一個是短網址映射到長網址一個是長網址映射到短網址

短網址是固定的格式: "http://tiny.url/" + 6個字符, 字符可任意。

為避免重復, 我們可以按照字典序依次使用, 或者在隨機生成的基礎上用一個集合來記錄是否使用過。

使用哈希函數(不可行)

如取 long url的 MD5 的最后 6 位:

快難以設計一個無哈希沖突的哈希算法

隨機生成 shortURL+DB去重

隨機取一個 6 位的 shortURL,若沒使用過,就綁定到改 long url。

public String long2Short(String url) { while(true) { String shortURL = randomShortURL(); if (!databse.filter(shortURL=shortURL).exists()) { database.create(shortURL=shortURL, longURL=url); return shortURL; } } }public class TinyUrl { public TinyUrl() { long2Short = new HashMap(); short2Long = new HashMap(); } /** * @param url a long url * @return a short url starts with http://tiny.url/ */ public String longToShort(String url) { if (long2Short.containsKey(url)) { return long2Short.get(url); } while (true) { String shortURL = generateShortURL(); if (!short2Long.containsKey(shortURL)) { short2Long.put(shortURL, url); long2Short.put(url, shortURL); return shortURL; } } } /** * @param url a short url starts with http://tiny.url/ * @return a long url */ public String shortToLong(String url) { if (!short2Long.containsKey(url)) { return null; } return short2Long.get(url); } private String generateShortURL() { String allowedChars = "0123456789" + "abcdefghijklmnopqrstuvwxyz" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; Random rand = new Random(); String shortURL = "http://tiny.url/"; for (int i = 0; i < 6; i++) { int index = rand.nextInt(62); shortURL += allowedChars.charAt(index); } return shortURL; }}

優點:實現簡單

缺點:生成短鏈接的速度,隨著短鏈接越多而越慢

關系型數據庫表:只需Short key和 long url兩列,并分別建立索引

也可使用 nosql,但需要建立兩張表:

根據 long 查詢 short key=longurl 列=shorturl value=null or timestamp根據 short 查詢 long key=shorturl 列=longurl value=null or timestamp

進制轉換 Base32(微博實現方案)

Base62:

將 6 位 short url 看做一個 62 進制數(0-9,a-z,A-Z)每個 short url 對應到一個整數該整數對應 DB 表的主鍵

6 位可表示的不同 URL:

5 位 = 62^5=0.9B= 9億6 位 = 62^6=57B= 570億7 位 = 62^7=3.5T= 35000億

優點:效率高

缺點:強依賴于全局的自增 id

public class TinyUrl { public static int GLOBAL_ID = 0; private HashMap id2url = new HashMap(); private HashMap url2id = new HashMap(); private String getShortKey(String url) { return url.substring("http://tiny.url/".length()); } private int toBase62(char c) { if (c >= "0" && c <= "9") { return c - "0"; } if (c >= "a" && c <= "z") { return c - "a" + 10; } return c - "A" + 36; } private int shortKeytoID(String short_key) { int id = 0; for (int i = 0; i < short_key.length(); ++i) { id = id * 62 + toBase62(short_key.charAt(i)); } return id; } private String idToShortKey(int id) { String chars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; String short_url = ""; while (id > 0) { short_url = chars.charAt(id % 62) + short_url; id = id / 62; } while (short_url.length() < 6) { short_url = "0" + short_url; } return short_url; } /** * @param url a long url * @return a short url starts with http://tiny.url/ */ public String longToShort(String url) { if (url2id.containsKey(url)) { return "http://tiny.url/" + idToShortKey(url2id.get(url)); } GLOBAL_ID++; url2id.put(url, GLOBAL_ID); id2url.put(GLOBAL_ID, url); return "http://tiny.url/" + idToShortKey(GLOBAL_ID); } /** * @param url a short url starts with http://tiny.url/ * @return a long url */ public String shortToLong(String url) { String short_key = getShortKey(url); int id = shortKeytoID(short_key); return id2url.get(id); }}

因為要用到自增 id,所以只能用關系型 DB 表:

id主鍵、long url(索引)

4.Scale

如何提高響應速度,和直接打開原鏈接一樣的效率。

明確,這是個讀多寫少業務。

4.1 緩存提速(Cache Aside)

緩存需存儲兩類數據:

long2short(生成新 short url 需要)short2long(查詢 short url 時需要)4.2 CDN

利用地理位置信息提速。

優化服務器訪問速度:

不同地區,使用通不同 web 服務器通過 dns 解析不同地區用戶到不同服務器

優化數據訪問速度

使用中心化的 MySQL+分布式的 Redis一個 MySQL 配多個 Redis,Redis 跨地區分布4.3 何時需要多臺 DB 服務器

cache 資源不夠或命中率低

寫操作過多

越來越多請求無法通過 cache 滿足

多臺DB服務器可以優化什么?

?解決存不下:存儲

?解決忙不過:qps

那么 tiny url 的主要問題是啥?存儲是沒問題的,重點是 qps。那么,如何 sharding 呢?

垂直拆分:將多張表分別分配給多臺機器。對此不適用,只有兩列,無法再拆分。

橫向拆分:

若id、shortURL 做分片鍵:

?long2short 查詢時,只能廣播給 N 臺 db 都去查詢

?為何要查 long2short?避免重復創建呀

?若不需要避免重復創建,則這樣可行

用 long url 做分片鍵:

short2long 查詢時,只能廣播給 N 臺 DB 查詢。

4.3.1 分片鍵選擇

若一個 long 可對應多個 short

?使用 cache 緩存所有 long2short

?在為一個 long url 創建 short url 時,若 cache miss,則創建新 short

若一個 long 只能對應一個 short

?若使用隨機生成算法

?兩張表,一張存儲 long2short,一張存儲short2long

?每個映射關系存兩份,則能同時支持 long2short short2long 查詢

?若使用 base62 進制轉換法

?有個嚴重問題,多臺機器之間如何維護一個全局自增的 id?

?一般關系型DB只支持在一臺機器上實現這臺機器上全局自增的 id

4.4 全局自增 id

4.4.1 專用一臺 DB 做自增服務

該 DB不存儲真實數據,也不負責其他查詢。

為避免單點故障,可能需要多臺 DB。

4.4.2 使用 zk

但使用全局自增 id 不是解決 tiny url最佳方案。Generating a Distributed Sequence Number

4.5 基于 base62 的分片策略

Hash(long_url)%62作為分片鍵

并將 hash(long_url)%62直接放到 short url

若原來的 short key 是 AB1234,則現在的 short key 是

hash(long_url) % 62 + AB1234若 hash(long_url)%62=0,那就是0AB1234

這樣,就能同時通過 short、long 得到分片鍵。

缺點:DB 的機器數目不能超過 62。

所以,最后最佳架構:

4.6 還能優化嗎?

web server 和 database 之間的通信。

中心化的服務器集群和跨地域的 web server 之間通信較慢:如中國的 Server 需訪問美國的 DB。

為何不讓中國的 Server 訪問中國的 DB 呢?

若數據重復寫到中國 DB,如何解決一致性問題?很難解決!

思考用戶的習慣:

中國用戶訪問時,會被 DNS 分配中國的服務器中國用戶訪問的網站一般都是中國的網站所以可按網站的地域信息來 sharding如何獲得網站的地域信息?只需將用戶常訪問的網站匯總在一張表。中國用戶訪問美國網站咋辦?就中國 server 訪問美國 db,也不會慢太多中訪中是用戶主流,優化系統就是針對主要需求

于是,得到最終架構:

還可以維護一份域名白名單,訪問對應地域的 DB。

5.用戶自定義短鏈接

實現一個顧客短網址,使得顧客能創立他們自己的短網址。即你需要在前文基礎上再實現一個createCustom。createCustom。

需實現三個方法:

long2Short(url)把一個長網址轉換成一個以http://tiny.url/開頭的短網址long2Short(url)把一個長網址轉換成一個以http://tiny.url/開頭的短網址short2Long(url)把一個短網址轉換成一個長網址short2Long(url)把一個短網址轉換成一個長網址createCustom(url, key)設定一個長網址的短網址為http://tiny.url/+keycreateCustom(url, key)設定一個長網址的短網址為http://tiny.url/+key

注意:

long2Short生成的短網址的key的長度應該等于6 (不算域名和反斜杠)??梢允褂玫淖址挥衃a-zA-Z0-9]。如:abcD9Elong2Short生成的短網址的key的長度應該等于6 (不算域名和反斜杠)??梢允褂玫淖址挥衃a-zA-Z0-9]。如:abcD9E任意兩個長的url不會對應成同一個短url,反之亦然如果createCustom不能完成用戶期望的設定, 那么應該返回"error", 反之如果成功將長網址與短網址對應,應該返回這個短網址createCustom不能完成用戶期望的設定, 那么應該返回"error", 反之如果成功將長網址與短網址對應,應該返回這個短網址5.1 基于 Base62

在URLTable里,直接新增一列custom_url記錄對應的custom url是否可行?

不可行!對于大部分數據,該列其實都為空,就會浪費存儲空間。

新增一個表,存儲自定義 URL:CustomURLTable。

創建自定義短鏈接:在 CustomURLTable 中查詢和插入

根據長鏈接創建普通短鏈接:

先查詢CustomURLTable是否存在再在URLTable查詢和插入

同前文一樣,用兩個哈希表處理長網址和短網址之間的相互映射關系。需額外處理的是用戶設定的網址與已有沖突時,需返回 "error"。注意:若用戶設定的和已有恰好相同,則同樣應該返回短網址。

public class TinyUrl2 { private HashMap s2l = new HashMap(); private HashMap l2s = new HashMap(); private int cnt = 0; private final StringBuffer tinyUrl = new StringBuffer("http://tiny.url/"); private final String charset = "qwertyuiopasdfghjklzxcvbnm1234567890QWERTYUIOPASDFGHJKLZXCVBNM"; private String newShortUrl() { StringBuffer res = new StringBuffer(); for (int i = 0, j = cnt; i < 6; i++, j /= 62) res.append(charset.charAt(j % 62)); cnt++; return tinyUrl + res.toString(); } /* * @param long_url: a long url * @param key: a short key * @return: a short url starts with http://tiny.url/ */ public String createCustom(String long_url, String key) { String short_url = tinyUrl + key; if (l2s.containsKey(long_url)) { if (l2s.get(long_url).equals(short_url)) return short_url; else return "error"; } if (s2l.containsKey(short_url)) return "error"; l2s.put(long_url, short_url); s2l.put(short_url, long_url); return short_url; } /* * @param long_url: a long url * @return: a short url starts with http://tiny.url/ */ public String longToShort(String long_url) { if (l2s.containsKey(long_url)) return l2s.get(long_url); String short_url = newShortUrl(); l2s.put(long_url, short_url); s2l.put(short_url, long_url); return short_url; } /* * @param short_url: a short url starts with http://tiny.url/ * @return: a long url */ public String shortToLong(String short_url) { if (s2l.containsKey(short_url)) return s2l.get(short_url); return "error"; }}5.2 基于隨機生成算法

無需做任何改動,直接把custom url當short url創建即可!

參考:https://www.zhihu.com/question/29270034

關鍵詞: 系統設計 可以使用 實踐經驗 一般都是

上一篇:

下一篇:

X 關閉

X 關閉

久久国产精品一区二区三区四区,久色婷婷小香蕉久久,国产日韩欧美在线播放不卡,另类av一区二区
日韩视频在线观看免费| 欧美三区在线观看| 久久精品中文字幕免费mv| 亚洲综合精品一区二区| 午夜激情一区| 久久成人18免费观看| 中文在线不卡| 久久gogo国模啪啪人体图| 久久九九有精品国产23| 可以看av的网站久久看| 欧美手机在线视频| 国产一区二区三区久久悠悠色av| 欧美日韩国产影片| 国产精品成人免费| 国产精品成人观看视频国产奇米| 国产精品视频一二| 国产欧美日韩三区| 国产欧美精品在线播放| 国内精品伊人久久久久av一坑| 国产精品女同互慰在线看| 欧美日韩午夜精品| 国产精品日韩在线观看| 国产欧美精品日韩| 影音先锋日韩精品| 艳女tv在线观看国产一区| 亚洲开发第一视频在线播放| 亚洲人精品午夜在线观看| 欧美资源在线观看| 欧美日韩在线视频首页| 欧美体内she精视频| 国产专区欧美专区| 日韩小视频在线观看专区| 亚洲欧美日韩另类| 久久精品欧美| 国产精品国产三级国产普通话三级| 国产精品jizz在线观看美国| 久久久爽爽爽美女图片| 欧美日韩国产限制| 91久久线看在观草草青青| 亚洲精品国精品久久99热一| 欧美亚洲午夜视频在线观看| 美女图片一区二区| 国产精品成人一区二区三区吃奶| 国产精品网红福利| 免费成人av| 国产视频一区三区| 亚洲免费高清| 国产日韩专区| 一区二区三区欧美成人| 欧美成人精品三级在线观看| 久色成人在线| 国产精品美腿一区在线看| 亚洲电影在线播放| 欧美一区二区三区久久精品茉莉花| 欧美国产精品中文字幕| 国产精品国产一区二区| 韩国av一区二区三区在线观看| 国内精品久久久久国产盗摄免费观看完整版| 久久视频这里只有精品| 欧美激情视频给我| 韩国av一区二区三区四区| 亚洲最新视频在线播放| 欧美成人综合在线| 最新成人在线| 欧美日本在线观看| 亚洲九九精品| 欧美激情精品久久久久久黑人| 国产精品久久久久久久午夜| 狠狠色综合网站久久久久久久| 亚洲激情另类| 久久人人看视频| 亚洲片在线观看| 欧美日韩国产小视频在线观看| 在线精品亚洲一区二区| 亚洲欧美一区二区三区久久| 欧美精品一区在线观看| 一区二区三区自拍| 在线综合+亚洲+欧美中文字幕| 欧美色中文字幕| 一区二区三区回区在观看免费视频| 欧美三级午夜理伦三级中文幕| 狠色狠色综合久久| 亚洲欧美欧美一区二区三区| 久久伊人精品天天| 日韩一级黄色片| 国产精品乱码一区二三区小蝌蚪| 午夜精品一区二区三区在线| 欧美成人一区二区三区| 亚洲免费观看高清在线观看| 国产精品扒开腿做爽爽爽软件| 亚洲三级免费观看| 国产精品久久久久久模特| 日韩写真在线| 一区二区三区欧美激情| 欧美国产激情二区三区| 亚洲精品久久久久久久久久久久| 午夜国产不卡在线观看视频| 激情综合视频| 欧美成人激情在线| 亚洲风情亚aⅴ在线发布| 美日韩精品免费观看视频| 亚洲天堂偷拍| 欧美日本国产视频| 亚洲深夜福利网站| 欧美性做爰猛烈叫床潮| 亚洲一区二区三区视频播放| 亚洲美女精品一区| 欧美大片18| 国产伦精品一区二区三区高清版| 韩日视频一区| 一区二区国产在线观看| 欧美激情一区二区三区高清视频| 99国产精品一区| 亚洲欧洲av一区二区三区久久| 欧美三级在线播放| 午夜精品免费在线| 国产精品久久久久影院亚瑟| 久久久久久久欧美精品| 美日韩免费视频| 国产精品二区在线观看| 一区二区精品在线| 亚洲欧美另类久久久精品2019| 亚洲免费网站| 亚洲国产成人在线播放| 免费的成人av| 亚洲嫩草精品久久| 亚洲丁香婷深爱综合| 午夜精品久久久久久久99水蜜桃| 欧美日韩一区二区在线视频| 在线成人av.com| 久久久精品国产免费观看同学| 午夜精品一区二区三区在线| 亚洲免费视频中文字幕| 欧美日韩福利在线观看| 亚洲国内高清视频| 欧美在线视频在线播放完整版免费观看| 亚洲欧美成人一区二区在线电影| 欧美巨乳波霸| 国内伊人久久久久久网站视频| 免费在线看成人av| 亚洲一区二区精品在线| 国产精品五月天| 欧美人与性动交α欧美精品济南到| 国产日韩一区欧美| 亚洲一区二区三区在线观看视频| 久久亚洲私人国产精品va媚药| 日韩一区二区精品视频| 亚洲欧洲在线一区| 亚洲天堂网在线观看| 欧美日韩中文字幕精品| 亚洲欧洲一区二区天堂久久| 久久亚洲精品伦理| 最近看过的日韩成人| 久久久久久黄| 亚洲午夜小视频| 亚洲级视频在线观看免费1级| 欧美激情一区二区三区高清视频| 久久精品天堂| 亚洲小说欧美另类社区| 亚洲欧美在线磁力| 久久夜色精品国产欧美乱| 亚洲激情小视频| 性色av香蕉一区二区| 亚洲国产另类久久久精品极度| 欧美成人官网二区| 国产在线播精品第三| 国产精品婷婷| 亚洲男女自偷自拍图片另类| 欧美日本韩国| 美日韩精品视频免费看| 在线国产精品一区| 久久精品一区二区三区中文字幕| 亚洲视频免费在线观看| 国产精品老女人精品视频| 国产乱码精品一区二区三| 亚洲精品免费观看| 国产视频一区在线观看一区免费| 亚洲自啪免费| 日韩午夜黄色| 欧美性生交xxxxx久久久| 中文一区在线| 欧美精品一区二区三区久久久竹菊| 久久xxxx| 久久9热精品视频| 欧美色图五月天| 国产精品www色诱视频| 久久精品国语| 日韩系列欧美系列| 日韩亚洲在线| 欧美激情成人在线| 欧美一区二区三区播放老司机| 国产精品成人国产乱一区| 亚洲欧美日韩系列| 欧美成熟视频| 欧美精品乱码久久久久久按摩| 久久国产视频网| 国产女主播一区二区三区| 欧美午夜一区二区三区免费大片| 久久免费99精品久久久久久| 亚洲影院色在线观看免费|