1.mysql索引都有哪些原則? 索引的數據結構?B+ tree 和 B tree 有什麼區別? www.cnblogs.com/tgycoder/p/… 建索引的幾大原則 一、最左前綴匹配原則,很是重要的原則 mysql會一直向右匹配直到遇到範圍查詢(>、<、between、like)就中止匹配。好比a = 1 and b = 2 and c > 3 and d = 4,若是創建(a,b,c,d)順序的索引,d是用不到索引的, 若是創建(a,b,d,c)的索引則均可以用到,a,b,d的順序能夠任意調整。php
二、=和in能夠亂序
好比a = 1 and b = 2 and c = 3 創建(a,b,c)索引能夠任意順序,mysql的查詢優化器會幫你優化成索引能夠識別的形式。
三、儘可能選擇區分度高的列做爲索引
區分度的公式是count(distinct col)/count(*),表示字段不重複的比例,比例越大咱們掃描的記錄數越少,惟一鍵的區分度是1,而一些狀態、性別字段可能在大數據面前區分度就是0,那可 能有人會問,這個比例有什麼經驗值嗎?使用場景不一樣,這個值也很難肯定,通常須要join的字段咱們都要求是0.1以上,即平均1條掃描10條記錄。
四、索引列不能參與計算,保持列「乾淨」
好比from_unixtime(create_time) = ’2014-05-29’就不能使用到索引,緣由很簡單,b+樹中存的都是數據表中的字段值,但進行檢索時,須要把全部元素都應用函數才能比較,顯然成本 太大。因此語句應該寫成create_time = unix_timestamp(’2014-05-29’);
五、儘可能的擴展索引,不要新建索引
好比表中已經有a的索引,如今要加(a,b)的索引,那麼只須要修改原來的索引便可。
六、若是肯定有多少條數據,使用 limit 限制一下,MySQL在查找到對應條數的數據的時候,會中止繼續查找
七、利用查詢緩存,不少時候MySQL會對查詢結果進行cache,可是對應「動態」的數據會不cache,例如:
1 SELECT username FROM user WHERE signup_date >= CURDATE() 沒法使用cache
2 SELECT username FROM user WHERE signup_date >= '2017-05-06' 能夠cache
當使用了MySQL的一寫函數以後,MySQL沒法肯定結果是易變的,因此不會cache,還有now(),rand()
也同樣不開啓cache
八、join 語法,儘可能將小的表放在前面,在須要on的字段上,數據類型保持一致,並設置對應的索引,不然MySQL沒法使用索引來join查詢
九、在大表上作大量更新時,若是會鎖全表,則須要拆分執行,避免長時間鎖住表,致使其餘請求積累太多(InnoDB 支持行鎖,但前提是Where子句須要創建索引,沒有索引也同樣是鎖全表)
爲何要B+樹
複製代碼
因爲B+樹的數據都存儲在葉子結點中,分支結點均爲索引,方便掃庫,只須要掃一遍葉子結點便可,可是B樹由於其分支結點一樣存儲着數據,咱們要找到具體的數據,須要進行一次中序遍歷按序來掃,因此B+樹更加適合在區間查詢的狀況,因此一般B+樹用於數據庫索引,而B樹則經常使用於文件索引。html
這都是因爲B+樹和B具備這不一樣的存儲結構所形成的區別,以一個m階樹爲例。 關鍵字的數量不一樣;B+樹中分支結點有m個關鍵字,其葉子結點也有m個,其關鍵字只是起到了一個索引的做用,可是B樹雖然也有m個子結點,可是其只擁有m-1個關鍵字。 存儲的位置不一樣;B+樹中的數據都存儲在葉子結點上,也就是其全部葉子結點的數據組合起來就是完整的數據,可是B樹的數據存儲在每個結點中,並不只僅存儲在葉子結點上。 分支結點的構造不一樣;B+樹的分支結點僅僅存儲着關鍵字信息和兒子的指針(這裏的指針指的是磁盤塊的偏移量),也就是說內部結點僅僅包含着索引信息。 查詢不一樣;B樹在找到具體的數值之後,則結束,而B+樹則須要經過索引找到葉子結點中的數據才結束,也就是說B+樹的搜索過程當中走了一條從根結點到葉子結點的路徑。 blog.csdn.net/bigtree_372…java
1.選擇惟一性索引mysql
惟一性索引的值是惟一的,能夠更快速的經過該索引來肯定某條記錄。例如,學生表中學號是具備惟一性的字段。爲該字段創建惟一性索引能夠很快的肯定某個學生的信息。若是使用姓名的話,可能存在同名現象,從而下降查詢速度。nginx
2.爲常常須要排序、分組和聯合操做的字段創建索引程序員
常常須要ORDER BY、GROUP BY、DISTINCT和UNION等操做的字段,排序操做會浪費不少時間。若是爲其創建索引,能夠有效地避免排序操做。web
3.爲常做爲查詢條件的字段創建索引面試
若是某個字段常常用來作查詢條件,那麼該字段的查詢速度會影響整個表的查詢速度。所以,爲這樣的字段創建索引,能夠提升整個表的查詢速度。redis
4.限制索引的數目算法
索引的數目不是越多越好。每一個索引都須要佔用磁盤空間,索引越多,須要的磁盤空間就越大。修改表時,對索引的重構和更新很麻煩。越多的索引,會使更新表變得很浪費時間。
5.儘可能使用數據量少的索引
若是索引的值很長,那麼查詢的速度會受到影響。例如,對一個CHAR(100)類型的字段進行全文檢索須要的時間確定要比對CHAR(10)類型的字段須要的時間要多。
6.儘可能使用前綴來索引
若是索引字段的值很長,最好使用值的前綴來索引。例如,TEXT和BLOG類型的字段,進行全文檢索會很浪費時間。若是隻檢索字段的前面的若干個字符,這樣能夠提升檢索速度。
7.刪除再也不使用或者不多使用的索引
表中的數據被大量更新,或者數據的使用方式被改變後,原有的一些索引可能再也不須要。數據庫管理員應當按期找出這些索引,將它們刪除,從而減小索引對更新操做的影響。
8 . 最左前綴匹配原則,很是重要的原則。
mysql會一直向右匹配直到遇到範圍查詢(>、<、between、like)就中止匹配,好比a 1=」」 and=」」 b=」2」 c=」「> 3 and d = 4 若是創建(a,b,c,d)順序的索引,d是用不到索引的,若是創建(a,b,d,c)的索引則均可以用到,a,b,d的順序能夠任意調整。
9 .=和in能夠亂序。
好比a = 1 and b = 2 and c = 3 創建(a,b,c)索引能夠任意順序,mysql的查詢優化器會幫你優化成索引能夠識別的形式
10 . 儘可能選擇區分度高的列做爲索引。
區分度的公式是count(distinct col)/count(*),表示字段不重複的比例,比例越大咱們掃描的記錄數越少,惟一鍵的區分度是1,而一些狀態、性別字段可能在大數據面前區分度就 是0,那可能有人會問,這個比例有什麼經驗值嗎?使用場景不一樣,這個值也很難肯定,通常須要join的字段咱們都要求是0.1以上,即平均1條掃描10條 記錄
11 .索引列不能參與計算,保持列「乾淨」。
好比from_unixtime(create_time) = ’2014-05-29’就不能使用到索引,緣由很簡單,b+樹中存的都是數據表中的字段值,但進行檢索時,須要把全部元素都應用函數才能比較,顯然成本 太大。因此語句應該寫成create_time = unix_timestamp(’2014-05-29’);
12 .儘可能的擴展索引,不要新建索引。 好比表中已經有a的索引,如今要加(a,b)的索引,那麼只須要修改原來的索引便可
注意:選擇索引的最終目的是爲了使查詢的速度變快。上面給出的原則是最基本的準則,但不能拘泥於上面的準則。讀者要在之後的學習和工做中進行不斷的實踐。根據應用的實際狀況進行分析和判斷,選擇最合適的索引方式。 2.mysql有哪些存儲引擎?有啥區別?要詳細! MyISAM存儲引擎:不支持事務、也不支持外鍵,優點是訪問速度快,對事務完整性沒有 要求或者以select,insert爲主 InnoDB存儲引擎提供了具備提交、回滾和崩潰恢復能力的事務安全。可是對比MyISAM引擎,寫的處理效率會差一些,而且會佔用更多的磁盤空間以保留數據和索引。 InnoDB存儲引擎的特色:支持自動增加列,支持外鍵約束 Memory存儲引擎使用存在於內存中的內容來建立表。每一個memory表只實際對應一個磁盤文件,格式是.frm。memory類型的表訪問很是的快,由於它的數據是放在內存中的,而且默認使用HASH索引,可是一旦服務關閉,表中的數據就會丟失掉 Merge存儲引擎是一組MyISAM表的組合,這些MyISAM表必須結構徹底相同,merge表自己並無數據,對merge類型的表能夠進行查詢,更新,刪除操做,這些操做其實是對內部的MyISAM表進行的
3.設計高併發系統數據庫層面如何設計?數據庫鎖有哪些類型?如何實現? www.cnblogs.com/zhangj391/p… blog.csdn.net/tangkund321… www.cnblogs.com/bcphp/p/768… 分庫分表 讀寫分離 數據庫高可用 數據分級 粗細管道 (表層面 不用外鍵關聯 慢sql優化 索引等)
共享鎖S LOCK 容許事務讀一行數據 排他鎖 X LOCK 容許事務刪除或更新一行數據 page-level locking(頁級鎖) 鎖定表中某些行集合(稱作頁),被鎖定的行只對鎖定最初的線程是可行。若是另一個線程想要向這些行寫數據,它必須等到鎖被釋放。 ——————— InnoDB的鎖大體分爲: 3.1 行鎖 支持併發高,帶來最大的鎖開銷. 在存儲引擎層實現,服務器感知不到 3.2 表鎖 服務器會爲諸如: ALTER Table 之類的語句使用表鎖,忽略存儲引擎的鎖機制 但鎖的類型又分爲: (1). 共享鎖(S Lock) , 容許事務讀取一行數據 (2). 排他鎖(X Lock),容許事務刪除或更新一行數據.
分庫分表 1.如何設計動態擴容的分庫分表方案? blog.csdn.net/ht99582/art… 2.用過哪些數據庫分表的中間件,有啥有點和缺點?分庫分表中間件的設計原理 www.cnblogs.com/wangzhongqi… blog.csdn.net/kingice1014… 不管使用哪一種架構,核心邏輯均極爲類似,除了協議實現層不一樣(JDBC或數據庫協議),都會分爲分片規則配置、SQL解析、SQL改寫、SQL路由、SQL執行以及結果歸併等模塊。 3.我如今有一個未分庫分表的系統,之後系統需分庫分表,如何設計? www.cnblogs.com/fjwuyongzhi… 讓未分庫分表的系統切換到分表的系統上
4.分佈式事務如何解決?TCC?若是出現網絡問題怎麼辦? www.cnblogs.com/taiyonghai/… 1、結合MQ消息中間件實現的可靠消息最終一致性 2、TCC補償性事務解決方案(二階段提交,設置好回滾) 3、最大努力通知型方案
第一種方案:可靠消息最終一致性,須要業務系統結合MQ消息中間件實現,在實現過程當中須要保證消息的成功發送及成功消費。即須要經過業務系統控制MQ的消息狀態 第二種方案:TCC補償性,分爲三個階段TRYING-CONFIRMING-CANCELING。每一個階段作不一樣的處理。(2階段提交,設置好回滾) TRYING階段主要是對業務系統進行檢測及資源預留 CONFIRMING階段是作業務提交,經過TRYING階段執行成功後,再執行該階段。默認若是TRYING階段執行成功,CONFIRMING就必定能成功。 CANCELING階段是回對業務作回滾,在TRYING階段中,若是存在分支事務TRYING失敗,則須要調用CANCELING將已預留的資源進行釋放。 第三種方案:最大努力通知xing型,這種方案主要用在與第三方系統通信時,好比:調用微信或支付寶支付後的支付結果通知。這種方案也是結合MQ進行實現,例如:經過MQ發送http請求,設置最大通知次數。達到通知次數後即再也不通知。 具體的案例你也能夠參考下這篇博客,它上面的這個案例就是結合電商支付作的系統分佈式事務實現案例:www.roncoo.com/article/det…
基於事務消息的MQ方案是目前公認的較爲理想的分佈式事務解決方案,各大電商都在應用這一方案。種方式適合的業務場景普遍,並且比較可靠。不過這種方式技術實現的難度比較大。目前主流的開源MQ(ActiveMQ、RabbitMQ、Kafka)均未實現對事務消息的支持,因此需二次開發或者新造輪子。 www.cnblogs.com/taiyonghai/… 5.爲何要分庫分表? 單表容量有限 系統分離,不能以掛全掛 6.分佈式尋址方式有哪些算法?一致性hash知道嗎?
7.如何解決分庫分表主鍵問題?有什麼實現方案? 分佈式主鍵生成策略 www.jianshu.com/p/a0a3aa888…
代碼更清晰,處理邏輯更簡單 不用去考慮各類鎖的問題,不存在加鎖釋放鎖操做,沒有由於可能出現死鎖而致使的性能消耗 不存在多進程或者多線程致使的切換而消耗CPU
2.redis有什麼數據類型?在哪些場景下使用? String 應用場景:String是最經常使用的一種數據類型,普通的key/ value 存儲均可以歸爲此類.便可以徹底實現目前 Memcached 的功能,而且效率更高。還能夠享受Redis的定時持久化,操做日誌及 Replication等功能。除了提供與 Memcached 同樣的get、set、incr、decr 等操做外,Redis還提供了下面一些操做: 獲取字符串長度 往字符串append內容 設置和獲取字符串的某一段內容 設置及獲取字符串的某一位(bit) 批量設置一系列字符串的內容 Hash 經常使用命令:hget,hset,hgetall 等。 應用場景:在Memcached中,咱們常常將一些結構化的信息打包成HashMap,在客戶端序列化後存儲爲一個字符串的值,好比用戶的暱稱、年齡、性別、積分等,這時候在須要修改其中某一項時,一般須要將全部值取出反序列化後,修改某一項的值,再序列化存儲回去。這樣不只增大了開銷,也不適用於一些可能併發操做的場合(好比兩個併發的操做都須要修改積分)。而Redis的Hash結構能夠使你像在數據庫中Update一個屬性同樣只修改某一項屬性值。 List 好比twitter的關注列表,粉絲列表等均可以用Redis的list結構來實現。 Set Redis set對外提供的功能與list相似是一個列表的功能,特殊之處在於set是能夠自動排重的,當你須要存儲一個列表數據,又不但願出現重複數據時,set是一個很好的選擇,而且set提供了判斷某個成員是否在一個set集合內的重要接口,這個也是list所不能提供的。 Sets 集合的概念就是一堆不重複值的組合。利用Redis提供的Sets數據結構,能夠存儲一些集合性的數據,好比在微博應用中,能夠將一個用戶全部的關注人存在一個集合中,將其全部粉絲存在一個集合。Redis還爲集合提供了求交集、並集、差集等操做,能夠很是方便的實現如共同關注、共同喜愛、二度好友等功能,對上面的全部集合操做,你還能夠使用不一樣的命令選擇將結果返回給客戶端仍是存集到一個新的集合中。 實現方式: set 的內部實現是一個 value永遠爲null的HashMap,實際就是經過計算hash的方式來快速排重的,這也是set能提供判斷一個成員是否在集合內的緣由。
Sorted set Redis sorted set的使用場景與set相似,區別是set不是自動有序的,而sorted set能夠經過用戶額外提供一個優先級(score)的參數來爲成員排序,而且是插入有序的,即自動排序。當你須要一個有序的而且不重複的集合列表,那麼能夠選擇sorted set數據結構,好比twitter 的public timeline能夠以發表時間做爲score來存儲,這樣獲取時就是自動按時間排好序的。 另外還能夠用Sorted Sets來作帶權重的隊列,好比普通消息的score爲1,重要消息的score爲2,而後工做線程能夠選擇按score的倒序來獲取工做任務。讓重要的任務優先執行。 pub/sub Pub/Sub 從字面上理解就是發佈(Publish)與訂閱(Subscribe),在Redis中,你能夠設定對某一個key值進行消息發佈及消息訂閱,當一個key值上進行了消息發佈後,全部訂閱它的客戶端都會收到相應的消息。這一功能最明顯的用法就是用做實時消息系統,好比普通的即時聊天,羣聊等功能。
Transactions 誰說NoSQL都不支持事務,雖然Redis的Transactions提供的並非嚴格的ACID的事務(好比一串用EXEC提交執行的命令,在執行中服務器宕機,那麼會有一部分命令執行了,剩下的沒執行),可是這個Transactions仍是提供了基本的命令打包執行的功能(在服務器不出問題的狀況下,能夠保證一連串的命令是順序在一塊兒執行的,中間有會有其它客戶端命令插進來執行)。Redis還提供了一個Watch功能,你能夠對一個key進行Watch,而後再執行Transactions,在這過程當中,若是這個Watched的值進行了修改,那麼這個Transactions會發現並拒絕執行。
3.redis的複製如何實現?redis集羣模式如何實現的?redis的key如何尋址?
Redis 使用異步複製。 從 Redis 2.8 開始, 從服務器會以每秒一次的頻率向主服務器報告複製流(replication stream)的處理進度。 一個主服務器能夠有多個從服務器。 不只主服務器能夠有從服務器, 從服務器也能夠有本身的從服務器, 多個從服務器之間能夠構成一個圖狀結構。 複製功能不會阻塞主服務器: 即便有一個或多個從服務器正在進行初次同步, 主服務器也能夠繼續處理命令請求。 複製功能也不會阻塞從服務器: 只要在 redis.conf 文件中進行了相應的設置, 即便從服務器正在進行初次同步, 服務器也能夠使用舊版本的數據集來處理命令查詢。 不過, 在從服務器刪除舊版本數據集並載入新版本數據集的那段時間內, 鏈接請求會被阻塞。 你還能夠配置從服務器, 讓它在與主服務器之間的鏈接斷開時, 向客戶端發送一個錯誤。 複製功能能夠單純地用於數據冗餘(data redundancy), 也能夠經過讓多個從服務器處理只讀命令請求來提高擴展性(scalability): 好比說, 繁重的 SORT 命令能夠交給附屬節點去運行。 能夠經過複製功能來讓主服務器免於執行持久化操做: 只要關閉主服務器的持久化功能, 而後由從服務器去執行持久化操做便可。
doc.redisfans.com/topic/persi… Redis 提供了多種不一樣級別的持久化方式: RDB 持久化能夠在指定的時間間隔內生成數據集的時間點快照(point-in-time snapshot)。 AOF 持久化記錄服務器執行的全部寫操做命令,並在服務器啓動時,經過從新執行這些命令來還原數據集。 AOF 文件中的命令所有以 Redis 協議的格式來保存,新命令會被追加到文件的末尾。 Redis 還能夠在後臺對 AOF 文件進行重寫(rewrite),使得 AOF 文件的體積不會超出保存數據集狀態所需的實際大小。 Redis 還能夠同時使用 AOF 持久化和 RDB 持久化。 在這種狀況下, 當 Redis 重啓時, 它會優先使用 AOF 文件來還原數據集, 由於 AOF 文件保存的數據集一般比 RDB 文件所保存的數據集更完整。 你甚至能夠關閉持久化功能,讓數據只在服務器運行時存在。 瞭解 RDB 持久化和 AOF 持久化之間的異同是很是重要的, 如下幾個小節將詳細地介紹這這兩種持久化功能, 並對它們的相同和不一樣之處進行說明。
4.redis如何設計分佈式鎖?zk能夠嗎?如何實現?哪一個效率更高
獲取鎖的時候,使用setnx加鎖,並使用expire命令爲鎖添加一個超時時間,超過該時間則自動釋放鎖,鎖的value值爲一個隨機生成的UUID,經過此在釋放鎖的時候進行判斷。 獲取鎖的時候還設置一個獲取的超時時間,若超過這個時間則放棄獲取鎖。 釋放鎖的時候,經過UUID判斷是否是該鎖,如果該鎖,則執行delete進行鎖釋放。
查看目標Node是否已經建立,已經建立,那麼等待鎖。 若是未建立,建立一個瞬時Node,表示已經佔有鎖。 若是建立失敗,那麼證實鎖已經被其餘線程佔有了,那麼一樣等待鎖。 當釋放鎖,或者當前Session超時的時候,節點被刪除,喚醒以前等待鎖的線程去爭搶鎖。 www.jianshu.com/p/5d12a0101…
5.redis持久化?有什麼優缺點?具體底層實現?
6.redis的過時測略有哪些?LRU?寫代碼? 定時刪除 含義:在設置key的過時時間的同時,爲該key建立一個定時器,讓定時器在key的過時時間來臨時,對key進行刪除- 優勢:保證內存被儘快釋放 缺點: 若過時key不少,刪除這些key會佔用不少的CPU時間,在CPU時間緊張的狀況下,CPU不能把全部的時間用來作要緊的事兒,還須要去花時間刪除這些key 定時器的建立耗時,若爲每個設置過時時間的key建立一個定時器(將會有大量的定時器產生),性能影響嚴重 沒人用 惰性刪除 含義:key過時的時候不刪除,每次從數據庫獲取key的時候去檢查是否過時,若過時,則刪除,返回null。 優勢:刪除操做只發生在從數據庫取出key的時候發生,並且只刪除當前key,因此對CPU時間的佔用是比較少的,並且此時的刪除是已經到了非作不可的地步(若是此時還不刪除的話,咱們就會獲取到了已通過期的key了) 缺點:若大量的key在超出超時時間後,好久一段時間內,都沒有被獲取過,那麼可能發生內存泄露(無用的垃圾佔用了大量的內存) 按期刪除 含義:每隔一段時間執行一次刪除過時key操做 優勢: 經過限制刪除操做的時長和頻率,來減小刪除操做對CPU時間的佔用--處理"定時刪除"的缺點 按期刪除過時key--處理"惰性刪除"的缺點 缺點 在內存友好方面,不如"定時刪除" 在CPU時間友好方面,不如"惰性刪除" 難點 合理設置刪除操做的執行時長(每次刪除執行多長時間)和執行頻率(每隔多長時間作一次刪除)(這個要根據服務器運行狀況來定了) import java.util.LinkedHashMap; import java.util.Map;
public LRUCache<K, V> extends LinkedHashMap<K, V> { private int cacheSize;
public LRUCache(int cacheSize) { super(16, 0.75, true); this.cacheSize = cacheSize; }
protected boolean removeEldestEntry(Map.Entry<K, V> eldest) { return size() >= cacheSize; } }
1.dubbo的實現過程?註冊中心掛了能夠繼續通訊嗎? 服務容器負責啓動,加載,運行服務提供者。
2.zk原理?zk均可以作什麼?paxos算法知道嗎?說一下原理和實現? ZooKeeper數據模型的結構與Unix文件系統很相似,總體上能夠看做是一棵樹,每一個節點稱作一個ZNode。每一個ZNode均可以經過其路徑惟一標識,好比上圖中第三層的第一個ZNode, 它的路徑是/app1/c1。在每一個ZNode上可存儲少許數據
整體說來,paxos就是經過兩個階段肯定一個決議:Phase1:肯定誰的編號最高,只有編號最高者纔有權利提交proposal;Phase2:編號最高者提交proposal,若是沒有其餘節點提出更高編號的proposal,則該提案會被順利經過;不然,整個過程就會重來。你編號高,我比你更高,反覆如此,算法永遠沒法結束,這叫活鎖。FLP Impossibility已經證實,在異步通訊中不存在任何一致性算法,活鎖即是Paxos沒法解決的硬傷。
3.dubbo支持哪些序列化協議?hessian?他的數據結構呢?PB知道嗎?爲啥PB是效率最高的? dubbo共支持以下幾種通訊協議:
dubbo:// rmi:// hessian:// http:// webservice:// thrift:// memcached:// redis://
4.netty?netty能夠幹啥?NIO BIO AIO都是什麼?有什麼區別?
5.dubbo的複製均衡和高可用測略有那些?動態代理測略呢?
Dubbo提供了多種均衡策略,缺省爲random隨機調用 隨機,按權重設置隨機機率。 輪循,按公約後的權重設置輪循比率。 最少活躍調用數,相同活躍數的隨機,活躍數指調用先後計數差。使慢的提供者收到更少請求,由於越慢的提供者的調用先後計數差會越大。 一致性Hash,相同參數的請求老是發到同一提供者。
6.爲何要進行系統拆分?拆分不用dubbo能夠麼?dubbo和thrift有什麼區別? thrift其實只是一個跨平臺的序列化協議,跟dubbo中使用的hessian2或json等價。
分佈式消息隊列 1.爲何使用消息隊列?消息隊列有什麼有點和缺點?
2.如何保證消息隊列的高可用?如何保證消息不被重複消費? 參照rabbitmq ack機制,對消費的數據預存在某個位置,消費端必定要提供消費回饋,否則數據持久保存在那
在數據生產時避免數據丟失的方法: 只要能避免上述兩種狀況,那麼就能夠保證消息不會被丟失。 1)就是說在同步模式的時候,確認機制設置爲-1,也就是讓消息寫入leader和全部的副本。 2)還有,在異步模式下,若是消息發出去了,但尚未收到確認的時候,緩衝池滿了,在配置文件中設置成不限制阻塞超時的時間,也就說讓生產端一直阻塞,這樣也能保證數據不會丟失。 在數據消費時,避免數據丟失的方法:若是使用了storm,要開啓storm的ackfail機制;若是沒有使用storm,確認數據被完成處理以後,再更新offset值。低級API中須要手動控制offset值。
針對消息重複:將消息的惟一標識保存到外部介質中,每次消費時判斷是否處理過便可。
3.kafka,activemq,rocketmq,rabbitmq有什麼優缺點? blog.csdn.net/kaixuanfeng… rocketmq:順序消息、消息重複rocketmq不保證(業務端去重)、事務消息 4.如何讓你實現一個消息隊列,如何進行架構設計?說一下思路 mq 冪等 順序 延遲
順序性:保證生產者 - MQServer - 消費者是一對一對一的關係 分佈式搜索引擎 1,es的工做過程是如何實現的?如何實現分佈式的? www.cnblogs.com/tgzhu/p/609… www.cnblogs.com/licongyu/p/… 路由和分片 分片 文檔在索引的時候,須要肯定文檔存放到哪一個分片上去。(經過把 _id 做爲 routing 來計算 shard) 文檔在檢索的時候,須要肯定文檔處在具體哪一個分片上。(經過把 _id 做爲 routing 來計算 shard) 2.es在數據量很大的狀況下如何提升查詢效率?(10億) 億級規模的ES查詢優化實戰 能用filter就不用query filter拿到相應的doc後不計算score不用排序 query會對符合條件的doc計算score並進行排序 filter的查詢速度比query快不少
增長相關cache的配置 indices.cache.filter.size: 30% indices.fielddata.cache.size: 60% index.cache.field.type: soft indices.breaker.fielddata.limit: 70%
優化方案——總結 能用filter就不用query 增長冗餘字段將部分range aggregation查詢變成terms aggregation 爲經常使用字段增長配置,將fielddata的loading設成eager,儘可能多加載到內存 增長集羣的緩存資源,把內存儘可能多的用起來 Global ordinals Index warmer 調整aggregation的collect_mode 上SSD 使用bulk請求 而且每一個請求不超過幾十M,由於太大會致使內存使用過大 如何提升ES的性能 不要返回較大的結果集
ES是設計成一個搜索引擎的,只擅長返回匹配查詢較少文檔,若是須要返回很是多的文檔須要使用Scroll。
避免稀疏
由於ES是基於Lucene來索引和存儲數據的,因此對稠密的數據更有效。Lucene可以有效的肯定文檔是經過一個整數的文檔id,不管有沒有數據都會話費一個字節存儲id。稀疏主要影響norms和doc_values,一些能夠避免稀疏的推薦:
避免將不相關的數據放到相同的索引中
規範的文檔結構
使用相同的字段名來保存一樣的數據。
避免類型
不用norms和doc_values在稀疏字段
調整索引速度 使用bulk請求
而且每一個請求不超過幾十M,由於太大會致使內存使用過大
使用 multiple workers/threads發送數據到ES
多進程或者線程,若是看到TOO_MANY_REQUESTS (429)和EsRejectedExecutionException則說明ES跟不上索引的速度,當集羣的I/O或者CPU飽和就獲得了工做者的數量。
增長刷新間隔
index.refresh_interval默認是1s,能夠改爲30s以減小合併壓力。
在加載大量數據時候能夠暫時不用refresh和repliccas
index.refresh_interval to -1 and index.number_of_replicas to 0
禁用swapping
禁用swapping
給文件緩存分配內存
緩存是用來緩存I/O操做的,至少用通常的內存來運行ES文件緩存。
使用更快的硬件
使用SSD做爲存儲設備。 使用本地存儲,避免使用NFS或者SMB 注意使用虛擬存儲,好比亞馬遜的EBS 索引緩衝大小
indices.memory.index_buffer_size一般是JVM的0.1,確保他足夠處理至多512MB的索引。
調整搜索速度 給文件系統緩存大內存
至少給可用內存的一半到文件系統緩存。
使用更快的硬件
使用SSD做爲存儲設備。 使用性能更好的CPU,高併發 使用本地存儲,避免使用NFS或者SMB 注意使用虛擬存儲,好比亞馬遜的EBS 文檔建模
避免連接,嵌套會使查詢慢幾倍,而親自關係能使查詢慢幾百倍,因此若是一樣的問題能夠經過沒有連接的非規範回答就能夠提高速度。
預索引數據
映射
數值型數據不必定要映射成整形或者長整型
避免scripts
若是實在要使用,就用painless和expressions
強勢合併只讀索引
www.elastic.co/guide/en/el… 不要強勢合併正在寫的索引
準備全局順序
準備文件系統緩存
index.store.preload,若是內存不是很大會使搜索變得緩慢。
調整磁盤使用 禁用不須要的功能
不須要過濾時能夠禁用索引「index」:false 若是你不須要text字段的score,能夠禁用」norms」:false 若是不須要短語查詢能夠不索引positions"indexe_options":"freqs" 不用默認的動態字符串匹配
不要使用_all
使用best_compression
使用最小的足夠用的數值類型
byte,short,integer,long half_float,float,double
3.es的查詢是一個怎麼樣的過程?底層的lucence介紹一下?到排索引知道嗎? es和mongo有什麼區別?什麼場景下使用? 深分頁場景ES性能極差,ES應該主要仍是搜索、以及目前正在增強的用於數據分析。作存儲有些深分頁查詢場景因性能沒法使用。 Es更新後即時查詢較差,延遲高。mongo在併發條件下也強於es
1,如何設計一個高併發高可用系統? 高併發原則 無狀態 拆分 服務化 消息隊列 數據異構 緩存銀彈 高可用原則: 降級 限流 切流量 可回滾 3業務設計原則 防重設計 冪等設計 流程定義 狀態與狀態機 後臺系統操做可反饋 後臺系統審批化 文檔註釋 備份 2,如何限流?工做中怎麼作的?說一下具體實現?
限制總併發數(好比數據庫鏈接池、線程池) 限制瞬時併發數(如nginx的limit_conn模塊,用來限制瞬時併發鏈接數) 限制時間窗口內的平均速率(如Guava的RateLimiter、nginx的limit_req模塊,限制每秒的平均速率) 限制遠程接口調用速率 限制MQ的消費速率。 能夠根據網絡鏈接數、網絡流量、CPU或內存負載等來限流
3.緩存如何使用的?緩存使用不當會形成什麼後果? blog.csdn.net/u011277123/…
4.如何熔斷?熔斷框架有哪些?具體實現原理知道嗎? 相似現實世界中的「保險絲「,當某個異常條件被觸發,直接熔斷整個服務,而不是一直等到此服務超時。 熔斷的觸發條件能夠依據不一樣的場景有所不一樣,好比統計一個時間窗口內失敗的調用次數。 NetFlix Hydrix Hystrix爲每個依賴服務維護一個線程池(或者信號量),當線程池佔滿,該依賴服務將會當即拒絕服務而不是排隊等待 每一個依賴服務都被隔離開來,Hystrix 會嚴格控制其對資源的佔用,並在任何失效發生時,執行失敗回退邏輯。
hystrix語義爲「豪豬」,具備自我保護的能力。hystrix的出現即爲解決雪崩效應,它經過四個方面的機制來解決這個問題
隔離(線程池隔離和信號量隔離):限制調用分佈式服務的資源使用,某一個調用的服務出現問題不會影響其餘服務調用。 優雅的降級機制:超時降級、資源不足時(線程或信號量)降級,降級後能夠配合降級接口返回託底數據。 融斷:當失敗率達到閥值自動觸發降級(如因網絡故障/超時形成的失敗率高),熔斷器觸發的快速失敗會進行快速恢復。 緩存:提供了請求緩存、請求合併實現。 支持實時監控、報警、控制(修改配置) (1)線程池隔離模式:使用一個線程池來存儲當前的請求,線程池對請求做處理,設置任務返回處理超時時間,堆積的請求堆積入線程池隊列。這種方式須要爲每一個依賴的服務申請線程池,有必定的資源消耗,好處是能夠應對突發流量(流量洪峯來臨時,處理不完可將數據存儲到線程池隊裏慢慢處理) (2)信號量隔離模式:使用一個原子計數器(或信號量)來記錄當前有多少個線程在運行,請求來先判斷計數器的數值,若超過設置的最大線程個數則丟棄改類型的新請求,若不超過則執行計數操做請求來計數器+1,請求返回計數器-1。這種方式是嚴格的控制線程且當即返回模式,沒法應對突發流量(流量洪峯來臨時,處理的線程超過數量,其餘的請求會直接返回,不繼續去請求依賴的服務)
5.如何降級?如何進行系統拆分?如何進行數據庫拆分? 降級須要對下層依賴的業務分級,把產生故障的丟了,換一個輕量級的方案,是一種退而求其次的方法。 根據業務場景的不一樣,通常採用如下兩種模式: 第一種(最經常使用)若是服務失敗,則咱們經過fallback進行降級,返回靜態值。
第二種採用服務級聯的模式,若是第一個服務失敗,則調用備用服務,例如失敗重試或者訪問緩存失敗再去取數據庫。服務級聯的目的則是盡最大努力保證返回數據的成功性,但若是考慮不充分,則有可能致使級聯的服務崩潰(好比,緩存失敗了,把所有流量打到數據庫,瞬間致使數據庫掛掉)。所以級聯模式,也要慎用,增長了管理的難度。
1,說一下TCP/IP四層? 應用層:應用程序間溝通的層,如簡單電子郵件傳輸(SMTP)、文件傳輸協議(FTP)、網絡遠程訪問協議(Telnet)等。 傳輸層:在此層中,它提供了節點間的數據傳送服務,如傳輸控制協議(TCP)、用戶數據報協議(UDP)等,TCP和UDP給數據包加入傳輸數據並把它傳輸到下一層中,這一層負責傳送數據,而且肯定數據已被送達並接收。 互連網絡層:負責提供基本的數據封包傳送功能,讓每一塊數據包都可以到達目的主機(但不檢查是否被正確接收),如網際協議(IP)。 網絡接口層:對實際的網絡媒體的管理,定義如何使用實際網絡(如Ethernet、Serial Line等)來傳送數據。
2.http的工做流程?http1.0 1.1 2.0有哪些區別? 地址解析 如用客戶端瀏覽器請求這個頁面:localhost.com:8080/index.htm 從中分解出協議名、主機名、端口、對象路徑等部分,對於咱們的這個地址,解析獲得的結果以下: 協議名:http 主機名:localhost.com( 在這一步,須要域名系統DNS解析域名localhost.com,得主機的IP地址。) 端口:8080 對象路徑:/index.htm 封裝http請求數據包 封裝成tcp包,創建tcp鏈接(三次握手) 在HTTP工做開始以前,客戶機(Web瀏覽器)首先要經過網絡與服務器創建鏈接,該鏈接是經過TCP來完成的 客戶端發送請求 服務器響應 服務器關閉tcp鏈接
長鏈接 HTTP 1.0須要使用keep-alive參數來告知服務器端要創建一個長鏈接,而HTTP1.1默認支持長鏈接。 HTTP是基於TCP/IP協議的,建立一個TCP鏈接是須要通過三次握手的,有必定的開銷,若是每次通信都要從新創建鏈接的話,對性能有影響。所以最好能維持一個長鏈接,能夠用個長鏈接來發多個請求。 節約帶寬 HTTP 1.1支持只發送header信息(不帶任何body信息),若是服務器認爲客戶端有權限請求服務器,則返回100,不然返回401。客戶端若是接受到100,纔開始把請求body發送到服務器。 這樣當服務器返回401的時候,客戶端就能夠不用發送請求body了,節約了帶寬。 另外HTTP還支持傳送內容的一部分。這樣當客戶端已經有一部分的資源後,只須要跟服務器請求另外的部分資源便可。這是支持文件斷點續傳的基礎。 HOST域 如今能夠web server例如tomat,設置虛擬站點是很是常見的,也便是說,web server上的多個虛擬站點能夠共享同一個ip和端口。 HTTP1.0是沒有host域的,HTTP1.1才支持這個參數。 HTTP1.1 HTTP 2.0主要區別 多路複用 HTTP2.0使用了多路複用的技術,作到同一個鏈接併發處理多個請求,並且併發請求的數量比HTTP1.1大了好幾個數量級。 固然HTTP1.1也能夠多創建幾個TCP鏈接,來支持處理更多併發的請求,可是建立TCP鏈接自己也是有開銷的。 TCP鏈接有一個預熱和保護的過程,先檢查數據是否傳送成功,一旦成功過,則慢慢加大傳輸速度。所以對應瞬時併發的鏈接,服務器的響應就會變慢。因此最好能使用一個創建好的鏈接,而且這個鏈接能夠支持瞬時併發的請求。 關於多路複用,能夠參看學習NIO 。 數據壓縮 HTTP1.1不支持header數據的壓縮,HTTP2.0使用HPACK算法對header的數據進行壓縮,這樣數據體積小了,在網絡上傳輸就會更快。 服務器推送 意思是說,當咱們對支持HTTP2.0的web server請求數據的時候,服務器會順便把一些客戶端須要的資源一塊兒推送到客戶端,省得客戶端再次建立鏈接發送請求到服務器端獲取。這種方式很是合適加載靜態資源。 服務器端推送的這些資源其實存在客戶端的某處地方,客戶端直接從本地加載這些資源就能夠了,不用走網絡,速度天然是快不少的。 3.TCP三次握手,4次分手工做流程?畫圖?爲何不是5次或者2次? 4.畫一下https的工做流程?如何實現?如何防止被抓包? 客戶端發送請求到服務器端 服務器端返回證書和公開密鑰,公開密鑰做爲證書的一部分而存在 客戶端驗證證書和公開密鑰的有效性,若是有效,則生成共享密鑰並使用公開密鑰加密發送到服務器端 服務器端使用私有密鑰解密數據,並使用收到的共享密鑰加密數據,發送到客戶端 客戶端使用共享密鑰解密數據 SSL加密創建………
驗證消息的確來自微信服務器 經過 timestamp, nonce 以及雙方約定好的 token 構成一個簽名,可以驗證信息是否來自微信。
在這裏並不適用,由於api就是由用戶調用的。
算法 1,有一個文件,45億個阿拉伯數字,,如何去重?如何找出最大的那個? 方案1:申請512M的內存(2^32/8=512MB),一個bit位表明一個unsigned int值。讀入40億個數,設置相應的bit位,讀入要查詢的數,查看相應bit位是否爲1,爲1表示存在,爲0表示不存在。 mapreduce 數據結構 2.二叉樹,紅黑樹
1.class.forname和classloader有什麼區別 java中class.forName()和classLoader均可用來對類進行加載。 class.forName()前者除了將類的.class文件加載到jvm中以外,還會對類進行解釋,執行類中的static塊。 而classLoader只幹一件事情,就是將.class文件加載到jvm中,不會執行static中的內容,只有在newInstance纔會去執行static塊。 Class.forName(name, initialize, loader)帶參函數也可控制是否加載static塊。而且只有調用了newInstance()方法採用調用構造函數,建立類的對象
2.arraylist,hashmap ArrayList底層以數組實現,容許重複,默認第一次插入元素時建立數組的大小爲10,超出限制時會增長50%的容量,每次擴容都底層採用System.arrayCopy()複製到新的數組,初始化時最好能給出數組大小的預估值。
和LinkedList的區別
一、ArrayList是實現了基於動態數組的數據結構,LinkedList基於鏈表的數據結構。 二、對於隨機訪問get和set,ArrayList以爲優於LinkedList,由於LinkedList要移動指針。 三、對於新增和刪除操做add和remove(不是在尾部添加刪除),LinkedList比較佔優點,由於ArrayList要移動數據。
和Vector的區別 一、Vector和ArrayList幾乎是徹底相同的,惟一的區別在於Vector是同步類(synchronized),屬於強同步類。所以開銷就比ArrayList要大,訪問要慢。正常狀況下,大多數的Java程序員使用ArrayList而不是Vector,由於同步徹底能夠由程序員本身來控制。 二、Vector每次擴容請求其大小的2倍空間,而ArrayList是1.5倍。 三、Vector還有一個子類Stack.
LinkedList以雙向鏈表實現,容許重複。(以下Node的實現)並保留頭指針和尾指針。 鏈表無容量限制,但雙向鏈表自己使用了更多空間,也須要額外的鏈表指針操做。 按下標訪問元素—get(i)/set(i,e) 要悲劇的遍歷鏈表將指針移動到位(若是i>數組大小的一半,會從末尾移起)。 插入、刪除元素時修改先後節點的指針便可,但仍是要遍歷部分鏈表的指針才能移動到下標所指的位置,只有在鏈表兩頭的操做—add(), addFirst(),removeLast()或用iterator()上的remove()能省掉指針的移動
HashMap 工做原理:經過hash算法,經過put和get存儲和獲取對象。 存儲對象時,咱們將K/V傳給put方法時,它調用hashCode計算hash從而獲得bucket位置,進一步存儲,HashMap會根據當前bucket的佔用狀況自動調整容量(超過Load Factor則resize爲原來的2倍)。若是發生碰撞的時候,Hashmap經過鏈表將產生碰撞衝突的元素組織起來。若是一個bucket中碰撞衝突的元素超過某個限制(默認是8),則使用紅黑樹來替換鏈表,從而提升速度。 獲取對象時,咱們將K傳給get,它調用hashCode計算hash從而獲得bucket位置,並進一步調用equals()方法肯定鍵值對。
HashMap 包含以下幾個構造器: HashMap():構建一個初始容量爲 16,負載因子爲 0.75 的 HashMap。 ashMap(int initialCapacity):構建一個初始容量爲 initialCapacity,負載因子爲 0.75 的 HashMap。 HashMap(int initialCapacity, float loadFactor):以指定初始容量、指定的負載因子建立一個 HashMap。 HashMap的基礎構造器HashMap(int initialCapacity, float loadFactor)帶有兩個參數,它們是初始容量initialCapacity和負載因子loadFactor。 負載因子loadFactor衡量的是一個散列表的空間的使用程度,負載因子越大表示散列表的裝填程度越高,反之愈小。對於使用鏈表法的散列表來講,查找一個元素的平均時間是O(1+a),所以若是負載因子越大,對空間的利用更充分,然然後果是查找效率的下降;若是負載因子過小,那麼散列表的數據將過於稀疏,對空間形成嚴重浪費。
從Java 8開始,HashMap,ConcurrentHashMap和LinkedHashMap在處理頻繁衝突時將使用平衡樹來代替鏈表,當同一hash桶中的元素數量超過特定的值便會由鏈表切換到平衡樹,這會將get()方法的性能從O(n)提升到O(logn)。
1.redis線程模型,底層實現,如何實現高併發高可用持久化,redis集羣的擴容同步,redis序列化的方式,如何防止穿透 Redis 基於 Reactor 模式開發了本身的網絡事件處理器: 這個處理器被稱爲文件事件處理器(file event handler): 文件事件處理器使用 I/O 多路複用(multiplexing)程序來同時監聽多個套接字, 並根據套接字目前執行的任務來爲套接字關聯不一樣的事件處理器。 當被監聽的套接字準備好執行鏈接應答(accept)、讀取(read)、寫入(write)、關閉(close)等操做時, 與操做相對應的文件事件就會產生, 這時文件事件處理器就會調用套接字以前關聯好的事件處理器來處理這些事件。 雖然文件事件處理器以單線程方式運行, 但經過使用 I/O 多路複用程序來監聽多個套接字, 文件事件處理器既實現了高性能的網絡通訊模型, 又能夠很好地與 redis 服務器中其餘一樣以單線程方式運行的模塊進行對接, 這保持了 Redis 內部單線程設計的簡單性。
Redis sentinel(哨兵)模塊已經被集成在redis2.4+的版本中,主要爲 Redis 主從架構(M-S)的系統提供: 監控:系統中master/slave 可用性監控 通知:當被監控的redis實例出問題時,通知應用程序 自動故障轉移,M-S角色轉換等能力。從一個方面說是提升了redis集羣的可用性. Redis Sentinel 是一個分佈式系統,你能夠在一個系統中運行多個 Sentinel 進程(progress),這些進程使用流言協議(gossip protocols)來接收關於master是否下線的信息,並使用投票協議(agreement protocols)來決定是否執行自動故障遷移,以及選擇哪一個從服務器做爲新的主服務器。 sentinel的一些設計思路和zookeeper很是相似,事實上,你能夠不使用sentinel,而是本身開發一個監控redis的zk客戶端也可以完成相應的設計要求。
序列化的目的是將一個實現了Serializable接口的對象轉換成一個字節序列,能夠。 把該字節序列保存起來(例如:保存在一個文件裏),之後能夠隨時將該字節序列恢復爲原來的對象.
增量同步 Redis增量同步主要指Slave完成初始化後開始正常工做時,Master發生的寫操做同步到Slave的過程。一般狀況下,Master每執行一個寫命令就會向Slave發送相同的寫命令,而後Slave接收並執行。 全量同步 Redis全量複製通常發生在Slave初始化階段,這時Slave須要將Master上的全部數據都複製一份。具體步驟以下: 1)從服務器鏈接主服務器,發送SYNC命令; 2)主服務器接收到SYNC命名後,開始執行BGSAVE命令生成RDB文件並使用緩衝區記錄此後執行的全部寫命令; 3)主服務器BGSAVE執行完後,向全部從服務器發送快照文件,並在發送期間繼續記錄被執行的寫命令; 4)從服務器收到快照文件後丟棄全部舊數據,載入收到的快照; 5)主服務器快照發送完畢後開始向從服務器發送緩衝區中的寫命令; 6)從服務器完成對快照的載入,開始接收命令請求,並執行來自主服務器緩衝區的寫命令;
緩存穿透:
認識
緩存穿透是指查詢一個必定不存在的數據,因爲緩存是不命中時須要從數據庫查詢,查不到數據則不寫入緩存,這將致使這個不存在的數據每次請求都要到數據庫去查詢,形成緩存穿透。 解決辦法:
對全部可能查詢的參數以hash形式存儲,在控制層先進行校驗,不符合則丟棄。還有最多見的則是採用布隆過濾器,將全部可能存在的數據哈希到一個足夠大的bitmap中,一個必定不存在的數據會被這個bitmap攔截掉,從而避免了對底層存儲系統的查詢壓力。 也能夠採用一個更爲簡單粗暴的方法,若是一個查詢返回的數據爲空(無論是數 據不存在,仍是系統故障),咱們仍然把這個空結果進行緩存,但它的過時時間會很短,最長不超過五分鐘。 緩存雪崩
認識
若是緩存集中在一段時間內失效,發生大量的緩存穿透,全部的查詢都落在數據庫上,形成了緩存雪崩。 這個沒有完美解決辦法,但能夠分析用戶行爲,儘可能讓失效時間點均勻分佈。大多數系統設計者考慮用加鎖或者隊列的方式保證緩存的單線程(進程)寫,從而避免失效時大量的併發請求落到底層存儲系統上。 解決方法
在緩存失效後,經過加鎖或者隊列來控制讀數據庫寫緩存的線程數量。好比對某個key只容許一個線程查詢數據和寫緩存,其餘線程等待。 能夠經過緩存reload機制,預先去更新緩存,再即將發生大併發訪問前手動觸發加載緩存 不一樣的key,設置不一樣的過時時間,讓緩存失效的時間點儘可能均勻 作二級緩存,或者雙緩存策略。A1爲原始緩存,A2爲拷貝緩存,A1失效時,能夠訪問A2,A1緩存失效時間設置爲短時間,A2設置爲長期。
2.mq的原理 如何保證消息的可靠性傳輸 處理消息丟失和解決消息冪等。 mq消息的延遲和過時失效 本身設計一個消息中間件 可靠性:消息的落地,超時重傳和確認 冪等 上半場生成全局惟一ID,業務無關,保證同一條消息只投遞一次,由mq保證; 下半場冪等要求有全局惟一的businessid 保證只消費一次,業務惟一,對MQ透明。 mq的延遲 最多見方案啓動一個cron定時任務,將48小時未拼分的滴滴訂單取出評價爲5星。效率低下。 能夠設計一個環形隊列,1-3600,每一個slot是一個Set,裏面有屬性表明第幾圈掃描到此開始執行任務。 //redis zset 實現 用Map來存儲元數據。id做爲key,整個消息結構序列化(json/…)以後做爲value,放入元消息池中。 將id放入其中(有N個)一個zset有序列表中,以createTime+delay+priority做爲score。修改狀態爲正在延遲中 使用timer實時監控zset有序列表中top 10的數據 。 若是數據score<=當前時間毫秒就取出來,根據topic從新放入一個新的可消費列表(list)中,在zset中刪除已經取出來的數據,並修改狀態爲待消費 客戶端獲取數據只須要從可消費隊列中獲取就能夠了。而且狀態必須爲待消費 運行時間須要<=當前時間的 若是不知足 從新放入zset列表中,修改狀態爲正在延遲。若是知足修改狀態爲已消費。或者直接刪除元數據。
3.dubbo的原理 spi思想 如何進行服務治理 dubbo的服務降級 失敗重試 設計本身的RPC框架 blog.csdn.net/chao_19/art… spi: 當服務的提供者,提供了服務接口的一種實現以後,在jar包的META-INF/services/目錄裏同時建立一個以服務接口命名的文件。該文件裏就是實現該服務接口的具體實現類。而當外部程序裝配這個模塊的時候,就能經過該jar包META-INF/services/裏的配置文件找到具體的實現類名,並裝載實例化,完成模塊的注入。 經過mock的配置,能夠很好的實現dubbo服務降級
1.超時設置 DUBBO消費端設置超時時間須要根據業務實際狀況來設定, 若是設置的時間過短,一些複雜業務須要很長時間完成,致使在設定的超時時間內沒法完成正常的業務處理。 這樣消費端達到超時時間,那麼dubbo會進行重試機制,不合理的重試在一些特殊的業務場景下可能會引起不少問題,須要合理設置接口超時時間。 好比發送郵件,可能就會發出多份重複郵件,執行註冊請求時,就會插入多條重複的註冊數據。 (1)合理配置超時和重連的思路 對於核心的服務中心,去除dubbo超時重試機制,並從新評估設置超時時間。 業務處理代碼必須放在服務端,客戶端只作參數驗證和服務調用,不涉及業務流程處理 2.重連機制 dubbo在調用服務不成功時,默認會重試2次。 Dubbo的路由機制,會把超時的請求路由到其餘機器上,而不是本機嘗試,因此 dubbo的重試機器也能必定程度的保證服務的質量。 可是若是不合理的配置重試次數,當失敗時會進行重試屢次,這樣在某個時間點出現性能問題,調用方再連續重複調用, 系統請求變爲正常值的retries倍,系統壓力會大增,容易引發服務雪崩,須要根據業務狀況規劃好如何進行異常處理,什麼時候進行重試。
4.AQS原理 哪些地方用到了AQS/CAS ConcurrentHashMap原理 java線程模型。併發下出現那些問題
5.synchronized如何實現,和lock的區別 synchronized: 在資源競爭不是很激烈的狀況下,偶爾會有同步的情形下,synchronized是很合適的。緣由在於,編譯程序一般會盡量的進行優化synchronize,另外可讀性很是好,無論用沒用過5.0多線程包的程序員都能理解。
ReentrantLock: ReentrantLock提供了多樣化的同步,好比有時間限制的同步,能夠被Interrupt的同步(synchronized的同步是不能Interrupt的)等。在資源競爭不激烈的情形下,性能稍微比synchronized差點點。可是當同步很是激烈的時候,synchronized的性能一會兒能降低好幾十倍。而ReentrantLock確還能維持常態。
Atomic: 和上面的相似,不激烈狀況下,性能比synchronized略遜,而激烈的時候,也能維持常態。激烈的時候,Atomic的性能會優於ReentrantLock一倍左右。可是其有一個缺點,就是隻能同步一個值,一段代碼中只能出現一個Atomic的變量,多於一個同步無效。由於他不能在多個Atomic之間同步。 6.mysql主從同步延遲處理 2.MySQL數據庫主從同步延遲是怎麼產生的。
答:當主庫的TPS併發較高時,產生的DDL數量超過slave一個sql線程所能承受的範圍,那麼延時就產生了,固然還有就是可能與slave的大型query語句產生了鎖等待。
3.MySQL數據庫主從同步延遲解決方案
答:最簡單的減小slave同步延時的方案就是在架構上作優化,儘可能讓主庫的DDL快速執行。還有就是主庫是寫,對數據安全性較高,好比sync_binlog=1,innodb_flush_log_at_trx_commit = 1 之類的設置,而slave則不須要這麼高的數據安全,徹底能夠講sync_binlog設置爲0或者關閉binlog,innodb_flushlog也能夠設置爲0來提升sql的執行效率。另外就是使用比主庫更好的硬件設備做爲slave。
4.MySQL數據庫主從同步延遲產生的因素。
根據MyBatis的日誌顯示,程序被加載時 MyBatis從XML中讀取出各個SQL語句,而後根據XML指定的MAPPER位置綁定相應的接口 而後MyBatis會在自身內容進行動態代理,將各Mapper接口進行動態實現,因此雖然你沒有寫任何的具體JDBC代碼,但實際上MyBatis已經爲你作好了這些事情 而後你在Mapper.XXXXX具體調用的時候,就能夠操做數據庫了
簡單的來講,XML保存了你的SQL邏輯 MAPPER則起到了溝通程序和SQL之間的相互訪問 8.tomcat線程模型 一個或多個Acceptor線程,每一個線程都有本身的Selector,Acceptor只負責accept新的鏈接,一旦鏈接創建以後就將鏈接註冊到其餘Worker線程中。 多個Worker線程,有時候也叫IO線程,就是專門負責IO讀寫的。方式實現方式就是有專門的線程負責IO事件監聽,這些線程有本身的Selector,一旦監聽到有IO讀寫事件,並非像第一種實現方式那樣(本身去執行IO操做),而是將IO操做封裝成一個Runnable交給Worker線程池來執行,這種狀況每一個鏈接可能會被多個線程同時操做,相比第一種併發性提升了,可是也可能引來多線程問題,在處理上要更加謹慎些。tomcat的NIO模型就是第二種。 模塊化: Connector 組件是 Tomcat 中兩個核心組件之一,它的主要任務是負責接收瀏覽器的發過來的 tcp 鏈接請求,建立一個 Request 和 Response 對象分別用於和請求端交換數據,而後會產生一個線程來處理這個請求並把產生的 Request 和 Response 對象傳給處理這個請求的線程,處理這個請求的線程就是 Container 組件要作的事了. Container 是容器的父接口,全部子容器都必須實現這個接口,Container 容器的設計用的是典型的責任鏈的設計模式,它有四個子容器組件構成,分別是:Engine、Host、Context、Wrapper,這四個組件不是平行的,而是父子關係,Engine 包含 Host,Host 包含 Context,Context 包含 Wrapper
9.分佈式事務的場景和解決方案,redis和zk實現分佈式鎖 事務必須知足傳統事務的特性,即原子性,一致性,分離性和持久性。可是分佈式事務處理過程當中,
常看法決方案:
10.TCP三次握手和4次揮手爲何要這樣作
11.項目中的挑戰,怎麼解決
12.設計一個高併發/高可用系統 www.cnblogs.com/wangzhongqi… 13.分佈式環境下保持redis和mysql的數據一致性 Redis只用做cache,寫請求只交給MySQL處理。不然你就要本身去解決一個分佈式事務的問題 緩存只作失效,不作更新 高一致性狀況下不要用緩存
14.dubbo redis mq裏面踩過的坑 dubbo由於超時重試 產生雪崩現象,系統相應緩慢 redis批處理能夠用pipeline模式提升效率 總結: 一、緩存穿透:查詢一個必然不存在的數據。好比文章表,查詢一個不存在的id,每次都會訪問DB,若是有人惡意破壞,極可能直接對DB形成影響。 二、緩存失效:若是緩存集中在一段時間內失效,DB的壓力凸顯。這個沒有完美解決辦法,但能夠分析用戶行爲,儘可能讓失效時間點均勻分佈。 當發生大量的緩存穿透,例如對某個失效的緩存的大併發訪問就形成了緩存雪崩。
全網惟一一個從0開始幫助Java開發者轉作大數據領域的公衆號~
大數據技術與架構或者搜索import_bigdata關注~
海量【java和大數據的面試題+視頻資料】整理在公衆號,關注後能夠下載~