springboot第66集:字節(jié)跳動二面經(jīng),一文讓你走出微服務(wù)迷霧架構(gòu)周刊
MongoDB 可以應(yīng)對三高需求
具體的應(yīng)用場景:
- 社交場景, 使用 MongoDB 存儲用戶信息, 以及用戶發(fā)表的朋友圈信息, 通過地理位置索引實(shí)現(xiàn)附近的人, 地點(diǎn)等功能.
- 游戲場景, 使用 MongoDB 存儲游戲用戶信息, 用戶的裝備, 積分等直接以內(nèi)嵌文檔的形式存儲, 方便查詢, 高效率存儲和訪問.
- 物流場景, 使用 MongoDB 存儲訂單信息, 訂單狀態(tài)在運(yùn)送過程中會不斷更新, 以 MongoDB 內(nèi)嵌數(shù)組的形式來存儲, 一次查詢就能將訂單所有的變更讀取出來.
- 物聯(lián)網(wǎng)場景, 使用 MongoDB 存儲所有接入的智能設(shè)備信息, 以及設(shè)備匯報(bào)的日志信息, 并對這些信息進(jìn)行多維度的分析.
- 視頻直播, 使用 MongoDB 存儲用戶信息, 點(diǎn)贊互動信息等.
- admin: 從權(quán)限角度考慮, 這是
root數(shù)據(jù)庫, 如果將一個(gè)用戶添加到這個(gè)數(shù)據(jù)庫, 這個(gè)用戶自動繼承所有數(shù)據(jù)庫的權(quán)限, 一些特定的服務(wù)器端命令也只能從這個(gè)數(shù)據(jù)庫運(yùn)行, 比如列出所有的數(shù)據(jù)庫或者關(guān)閉服務(wù)器 - local: 數(shù)據(jù)永遠(yuǎn)不會被復(fù)制, 可以用來存儲限于本地的單臺服務(wù)器的集合 (部署集群, 分片等)
- config: Mongo 用于分片設(shè)置時(shí),
config數(shù)據(jù)庫在內(nèi)部使用, 用來保存分片的相關(guān)信息
線程池詳解
線程池用來處理異步任務(wù)或者并發(fā)執(zhí)行的任務(wù)
優(yōu)點(diǎn):
- 重復(fù)利用已創(chuàng)建的線程,減少創(chuàng)建和銷毀線程造成的資源消耗
- 直接使用線程池中的線程,提高響應(yīng)速度
- 提高線程的可管理性,由線程池同一管理
ThreadPoolExecutor
java中線程池使用ThreadPoolExecutor實(shí)現(xiàn)
corePoolSize:線程池的核心線程數(shù)量
maximumPoolSize:線程池允許創(chuàng)建的最大線程數(shù)量
keepAliveTime:線程活動保持時(shí)間
unit:線程活動保持時(shí)間的單位
workQueue:任務(wù)隊(duì)列,用來保存等待執(zhí)行任務(wù)的阻塞隊(duì)列
創(chuàng)建線程有三種方式
- 繼承
Thread類 - 實(shí)現(xiàn)
Runnable接口 - 實(shí)現(xiàn)
Callable接口
客戶端負(fù)載均衡器的實(shí)現(xiàn)原理是通過注冊中心,如 Nacos,將可用的服務(wù)列表拉取到本地(客戶端),再通過客戶端負(fù)載均衡器(設(shè)置的負(fù)載均衡策略)獲取到某個(gè)服務(wù)器的具體 ip 和端口,然后再通過 Http 框架請求服務(wù)并得到結(jié)果
從庫讀主庫寫,一般不要采用雙主或多主引入很多復(fù)雜性,同時(shí)目前很多拆分的解決方案同時(shí)也兼顧考慮了讀寫分離。
總體來講,MyISAM 適合
SELECT密集型的表,而 InnoDB 適合INSERT和UPDATE密集型的表
系統(tǒng)內(nèi)有一張5000W+的大表。跟蹤代碼發(fā)現(xiàn),該表是用于存儲資金流水的表格,關(guān)聯(lián)著眾多功能點(diǎn),同時(shí)也有眾多的下游系統(tǒng)在使用這張表的數(shù)據(jù)。進(jìn)一步的觀察發(fā)現(xiàn),這張表還在以每月600W+的數(shù)據(jù)持續(xù)增長,也就是說,不超過半年,這張表會增長到1個(gè)億!
這個(gè)數(shù)據(jù)量,對于mysql數(shù)據(jù)庫來說是絕對無法繼續(xù)維護(hù)的了,因此在接手系統(tǒng)兩個(gè)月后,我們便開起了大表拆分的專項(xiàng)工作。
- 涉及到流水表流水的接口超時(shí)頻發(fā),部分接口基本不可用
- 每日新增流水緩慢,主要是插入數(shù)據(jù)庫的時(shí)候非常慢
- 單表占用空間過大,DBA的數(shù)據(jù)庫監(jiān)控經(jīng)常報(bào)警
- 無法對表進(jìn)行變更,任何alter操作都會引起主從的高延遲和長時(shí)間鎖表
- 將流水大表數(shù)據(jù)拆分至各個(gè)分表,保證每張分表數(shù)據(jù)在1000W左右(經(jīng)驗(yàn)上看單表1000W的量對mysql來說沒啥壓力)
- 在拆表的前提下,針對不同接口的查詢條件進(jìn)行優(yōu)化,保證各個(gè)對外、對內(nèi)接口的可用性。徹底殺死m(xù)ysql慢查詢。
- 該表的數(shù)據(jù)可以說是整個(gè)財(cái)務(wù)系統(tǒng)最基礎(chǔ)的數(shù)據(jù),相關(guān)功能和下游系統(tǒng)非常多。這要求開發(fā)、測試和上線流程必須極其嚴(yán)密,任何小失誤都會引起大問題。
- 涉及的場景非常多。統(tǒng)計(jì)下來,一共有26個(gè)場景,需要改造32個(gè)mapper方法,具體需要改造的方法就更加無計(jì)其數(shù)了。
- 數(shù)據(jù)量非常大,遷移數(shù)據(jù)的過程必須保證系統(tǒng)穩(wěn)定。
- 用戶較多且功能重要。分表功能上線時(shí),必須盡量壓縮系統(tǒng)無法使用時(shí)長,同時(shí)需要保證系統(tǒng)可用性。這要求團(tuán)隊(duì)必須設(shè)計(jì)完整可靠的上線流程、數(shù)據(jù)遷移方案、回滾方案、降級策略。
- 表的拆分勢必帶來部分接口的變化,接口的變化又會帶來其他系統(tǒng)的改造。如何推動其他系統(tǒng)進(jìn)行改造,如何協(xié)調(diào)多方合作的開發(fā)、測試和上線是另一個(gè)難點(diǎn)。
image.png
采用sharding-jdbc作為分表插件。其優(yōu)勢如下:1、支持多種分片策略,自動識別=或in判斷具體在哪張分表里。2、輕量級,作為maven依賴引入即可,對業(yè)務(wù)的侵入性極低。
為提升查詢速度,在整個(gè)項(xiàng)目的初期,團(tuán)隊(duì)成員考慮引入ES存儲流水以提升查詢速度。
多表的分頁問題 拆表一定會引起分頁查詢的難度增加。由于各個(gè)表查出來的數(shù)據(jù)量不等,原始的sql語句limit不再適用,需要設(shè)計(jì)一個(gè)新方法便捷的獲取分頁信息。
單表優(yōu)化
除非單表數(shù)據(jù)未來會一直不斷上漲,否則不要一開始就考慮拆分,拆分會帶來邏輯、部署、運(yùn)維的各種復(fù)雜度,一般以整型值為主的表在千萬級以下,字符串為主的表在五百萬以下是沒有太大問題的。
而事實(shí)上很多時(shí)候 MySQL 單表的性能依然有不少優(yōu)化空間,甚至能正常支撐千萬級以上的數(shù)據(jù)量。
字段
- 盡量使用
TINYINT、SMALLINT、MEDIUM_INT作為整數(shù)類型而非INT,如果非負(fù)則加上UNSIGNED -
VARCHAR的長度只分配真正需要的空間 - 使用枚舉或整數(shù)代替字符串類型
- 盡量使用
TIMESTAMP而非DATETIME - 單表不要有太多字段,建議在 20 以內(nèi)
- 避免使用
NULL字段,很難查詢優(yōu)化且占用額外索引空間 - 用整型來存 IP
- 索引并不是越多越好,要根據(jù)查詢有針對性的創(chuàng)建,考慮在
WHERE和ORDER BY命令上涉及的列建立索引,可根據(jù)EXPLAIN來查看是否用了索引還是全表掃描 - 應(yīng)盡量避免在
WHERE子句中對字段進(jìn)行NULL值判斷,否則將導(dǎo)致引擎放棄使用索引而進(jìn)行全表掃描 - 值分布很稀少的字段不適合建索引,例如"性別"這種只有兩三個(gè)值的字段
- 字符字段只建前綴索引
- 字符字段最好不要做主鍵
- 不用外鍵,由程序保證約束
- 盡量不用
UNIQUE,由程序保證約束 - 使用多列索引時(shí)主意順序和查詢條件保持一致,同時(shí)刪除不必要的單列索引
- 可通過開啟慢查詢?nèi)罩緛碚页鲚^慢的 SQL
- 不做列運(yùn)算:
SELECT id WHERE age+1=10,任何對列的操作都將導(dǎo)致表掃描,它包括數(shù)據(jù)庫教程函數(shù)、計(jì)算表達(dá)式等等,查詢時(shí)要盡可能將操作移至等號右邊 - sql 語句盡可能簡單:一條 sql 只能在一個(gè) cpu 運(yùn)算;大語句拆小語句,減少鎖時(shí)間;一條大sql 可以堵死整個(gè)庫
- 不用
SELECT * -
OR改寫成IN:OR的效率是 n 級別,IN的效率是 log(n) 級別,IN的個(gè)數(shù)建議控制在 200 以內(nèi) - 不用函數(shù)和觸發(fā)器,在應(yīng)用程序?qū)崿F(xiàn)
- 避免
%xxx式查詢 - 少用
JOIN - 使用同類型進(jìn)行比較,比如用 '123' 和 '123' 比, 123 和 123 比
- 盡量避免在
WHERE子句中使用!=或<>操作符,否則將引擎放棄使用索引而進(jìn)行全表掃描 - 對于連續(xù)數(shù)值,使用
BETWEEN不用IN:SELECT id FROM t WHERE num BETWEEN 1 AND 5 - 列表數(shù)據(jù)不要拿全表,要使用
LIMIT來分頁,每頁數(shù)量也不要太大
InnoDB 在 MySQL 5.5 后成為默認(rèn)索引,它的特點(diǎn)是:
- 支持行鎖,采用 MVCC 來支持高并發(fā)
- 支持事務(wù)
- 支持外鍵
- 支持崩潰后的安全恢復(fù)
- 不支持全文索引
MySQL大文本存儲壓縮
select
table_name as '表名',
table_rows as '記錄數(shù)',
truncate(data_length/1024/1024, 2) as '數(shù)據(jù)容量(MB)',
truncate(index_length/1024/1024, 2) as '索引容量(MB)',
truncate(DATA_FREE/1024/1024, 2) as '碎片占用(MB)'
from
information_schema.tables
where
table_schema=${數(shù)據(jù)庫名}
order by
data_length desc, index_length desc;
什么是分布式事務(wù)問題?
單體應(yīng)用
單體應(yīng)用中,一個(gè)業(yè)務(wù)操作需要調(diào)用三個(gè)模塊完成,此時(shí)數(shù)據(jù)的一致性由本地事務(wù)來保證。
image.png
負(fù)載均衡通器常有兩種實(shí)現(xiàn)手段,一種是服務(wù)端負(fù)載均衡器,另一種是客戶端負(fù)載均衡器,而我們今天的主角 Ribbon 就屬于后者——客戶端負(fù)載均衡器。
服務(wù)端負(fù)載均衡器的問題是,它提供了更強(qiáng)的流量控制權(quán),但無法滿足不同的消費(fèi)者希望使用不同負(fù)載均衡策略的需求,而使用不同負(fù)載均衡策略的場景確實(shí)是存在的,所以客戶端負(fù)載均衡就提供了這種靈活性。 然而客戶端負(fù)載均衡也有其缺點(diǎn),如果配置不當(dāng),可能會導(dǎo)致服務(wù)提供者出現(xiàn)熱點(diǎn),或者壓根就拿不到任何服務(wù)的情況
Ribbon 介紹
Ribbon 是 Spring Cloud 技術(shù)棧中非常重要的基礎(chǔ)框架,它為 Spring Cloud 提供了負(fù)載均衡的能力,比如 Fegin 和 OpenFegin 都是基于 Ribbon 實(shí)現(xiàn)的,就連 Nacos 中的負(fù)載均衡也使用了 Ribbon 框架。
Ribbon 框架的強(qiáng)大之處在于,它不僅內(nèi)置了 7 種負(fù)載均衡策略,同時(shí)還支持用戶自定義負(fù)載均衡策略,所以其開放性和便利性也是它得以流行的主要原因。
mongodb-driver是mongo官方推出的java連接mongoDB的驅(qū)動包,相當(dāng)于JDBC驅(qū)動。我們通過一個(gè)入門的案例來了解mongodb-driver 的基本使用。
秒殺場景下的業(yè)務(wù)梳理——Redis分布式鎖的優(yōu)化
商品秒殺本質(zhì)上其實(shí)還是商品購買,所以我們需要準(zhǔn)備一張訂單表來記錄對應(yīng)的秒殺訂單。
這里就涉及到了一個(gè)訂單 id 的問題了,我們是否可以像其他表一樣使用數(shù)據(jù)庫自身的自增 id 呢?
鎖有兩種:
一,悲觀鎖: 認(rèn)為線程安全問題一定會發(fā)生,因此在操作數(shù)據(jù)之前先獲取鎖,確保線程串行執(zhí)行。例如Synchronized、Lock都屬于悲觀鎖;
二,樂觀鎖: 認(rèn)為線程安全問題不一定會發(fā)生,因此不加鎖,只是在更新數(shù)據(jù)時(shí)去判斷有沒有其它線程對數(shù)據(jù)做了修改。
- 官方驅(qū)動說明和下載:mongodb.github.io/mongo-java-…[1]
- 官方驅(qū)動示例文檔:mongodb.github.io/mongo-java-…[2]
5.3.2 SpringDataMongoDB
SpringData家族成員之一,用于操作MongoDB的持久層框架,封裝了底層的mongodb-driver。
官網(wǎng)主頁: projects.spring.io/spring-data…[3]
在 MongoDB 中, 數(shù)據(jù)庫和集合都不需要手動創(chuàng)建, 當(dāng)我們創(chuàng)建文檔時(shí), 如果文檔所在的集合或者數(shù)據(jù)庫不存在, 則會自動創(chuàng)建數(shù)據(jù)庫或者集合
- 數(shù)據(jù)庫 (database)
- 數(shù)據(jù)庫是一個(gè)倉庫, 存儲集合 (collection)
- 集合 (collection)
- 類似于數(shù)組, 在集合中存放文檔
- 文檔 (document)
- 文檔型數(shù)據(jù)庫的最小單位, 通常情況, 我們存儲和操作的內(nèi)容都是文檔
單機(jī)搭建mongodb分布式集群(副本集 + 分片集群)
MongoDB是一個(gè)開源, 高性能, 無模式的文檔型數(shù)據(jù)庫, 當(dāng)初的設(shè)計(jì)就是用于簡化開發(fā)和方便擴(kuò)展, 是NoSQL數(shù)據(jù)庫產(chǎn)品中的一種.是最 像關(guān)系型數(shù)據(jù)庫(MySQL)的非關(guān)系型數(shù)據(jù)庫. 它支持的數(shù)據(jù)結(jié)構(gòu)非常松散, 是一種類似于 JSON 的 格式叫BSON, 所以它既可以存儲比較復(fù)雜的數(shù)據(jù)類型, 又相當(dāng)?shù)撵`活. MongoDB中的記錄是一個(gè)文檔, 它是一個(gè)由字段和值對(?eld:value)組成的數(shù)據(jù)結(jié)構(gòu).MongoDB文檔類似于JSON對象, 即一個(gè)文檔認(rèn) 為就是一個(gè)對象.字段的數(shù)據(jù)類型是字符型, 它的值除了使用基本的一些類型外, 還可以包括其他文檔, 普通數(shù)組和文檔數(shù)組.
“最像關(guān)系型數(shù)據(jù)庫的 NoSQL 數(shù)據(jù)庫” . MongoDB 中的記錄是一個(gè)文檔, 是一個(gè) key-value pair. 字段的數(shù)據(jù)類型是字符型, 值除了使用基本的一些類型以外, 還包括其它文檔, 普通數(shù)組以及文檔數(shù)組
MySQL主從復(fù)制集群搭建—binlog二進(jìn)制文件方式
binlog 簡介
Mysql中有一個(gè)binlog二進(jìn)制日志,這個(gè)日志會記錄下主服務(wù)器所有修改了的SQL語句,從服務(wù)器把主服務(wù)器上的binlog二進(jìn)制日志,在指定的位置開始復(fù)制主服務(wù)器所有修改的語句,在從服務(wù)器上執(zhí)行一遍。
簡而言之就是,主服務(wù)器會把create、update、delete語句都記錄到一個(gè)二進(jìn)制文件中(binlog),從服務(wù)器讀取這個(gè)文件,執(zhí)行一遍文件中記錄的create、update、delete語句。從而實(shí)現(xiàn)主從數(shù)據(jù)同步。
配置主從庫 my.ini 或者 my.cnf 文件
my.ini是Windows系統(tǒng)的,my.cnf是Linux系統(tǒng)的
在 111 和 222 的 my.ini 中的[mysqld]節(jié)點(diǎn)下配置
- server-id =
唯一ID:主服務(wù)器唯一 ID,一般設(shè)置為機(jī)器 IP 地址后三位- log-bin =
二進(jìn)制日志文件存放路徑:這個(gè)是啟動并記錄 binlog 日志- log-err =
錯(cuò)誤日志路徑(可選):啟動錯(cuò)誤日志- read-only =
0:0是讀寫都行(主庫),1是只讀(從庫)- binlog-lgnore-db=
數(shù)據(jù)庫名(可選):設(shè)置不要主從復(fù)制的數(shù)據(jù)庫- binlog-do-db =
數(shù)據(jù)庫名(可選):需要復(fù)制的數(shù)據(jù)庫名
- 三臺服務(wù)器:192.168.216.111、192.168.216.222、192.168.216.333
當(dāng)主庫和從庫都配置完 my.ini 文件之后,還需要主庫建立一個(gè)授權(quán)用戶,讓從庫能通過這個(gè)用戶登錄到主庫上。
grant replication slave on *.* TO '用戶名'@'從機(jī)IP' identified by '密碼';(建立授權(quán)用戶)
flush privileges;(刷新mysql的系統(tǒng)權(quán)限相關(guān)表)
- 在從機(jī)上試試可否連接上主機(jī)
222從庫執(zhí)行: mysql -h 主機(jī)IP -usally -pilovesally
- 如果連接失敗,看看是不是防火墻的原因,配置防火墻的 IP 規(guī)則
開始主從復(fù)制
- 查看 master 111 主機(jī)狀態(tài)
show master status;
主要看File和Position兩個(gè)參數(shù),File代表從哪個(gè)日志文件里同步數(shù)據(jù),Position代表從這個(gè)文件的什么位置開始同步數(shù)據(jù),binlog-do-db 和 binlog-lgnore-db 意思為同步哪幾個(gè)數(shù)據(jù)庫和不同步哪幾個(gè)數(shù)據(jù)庫。
- 從庫登錄主庫設(shè)置同步數(shù)據(jù)文件
如果之前做過同步數(shù)據(jù),那么請先停止(stop slave;),否則會報(bào)錯(cuò)。
222執(zhí)行: MASTER_HOST='主機(jī)IP', MASTER_USER='主機(jī)用戶名', MASTER_PASSWORD='主機(jī)密碼', MASTER_LOG_FILE='File名字', MASTER_LOG_POS=Position數(shù)字;
- 啟動從庫復(fù)制功能
start slave;
- 查看從庫同步狀態(tài)
show slave status\G;
auto_increment_increment=2 #步長值auto_imcrement。一般有n臺主MySQL就填n
auto_increment_offset=1 #起始值。一般填第n臺主MySQL
mysql數(shù)據(jù)同步:canal搭建主從|集群架構(gòu)
從架構(gòu)方式上出發(fā),我們用來保證服務(wù)高可用的手段主要是主從架構(gòu)、集群架構(gòu)。有時(shí)我們也把主從歸結(jié)到集群架構(gòu)中,但嚴(yán)格意義上講,集群架構(gòu)是指多節(jié)點(diǎn)同時(shí)運(yùn)行,而主從架構(gòu)同一時(shí)刻只有一個(gè)節(jié)點(diǎn)運(yùn)行,另一個(gè)節(jié)點(diǎn)作為備用,只有當(dāng)主節(jié)點(diǎn)宕機(jī)時(shí),備用節(jié)點(diǎn)才會啟用。
我們首先要理解canal實(shí)現(xiàn)數(shù)據(jù)同步的依賴于binlog,也依賴于mysql dump指令,binlog本身的特性就要求數(shù)據(jù)原子性、隔離性,有序性,同時(shí)mysql dump指令是比較占用mysql服務(wù)器資源的,所以要盡可能少的避免,為此canal服務(wù)端同一時(shí)刻只能有一個(gè)節(jié)點(diǎn)來讀取binlog進(jìn)行同步。
因此在這樣的基礎(chǔ)之上,canal的集群模式實(shí)際上就是主從模式。那么我們要進(jìn)行搭建的也就是主從。
我們知道canal中有服務(wù)端deployer和客戶端adapter,服務(wù)端負(fù)責(zé)從mysql中讀取binlog,而客戶端負(fù)責(zé)從服務(wù)端讀取同步過來的binlog數(shù)據(jù),處理后將同步數(shù)據(jù)發(fā)送到目標(biāo)服務(wù)端,比如redis、es或其他的關(guān)系性數(shù)據(jù)庫等
zookeeper搭建
采用docker搭建zk
docker run -d -e TZ="Asia/Shanghai" -p 2181:2181 --name zookeeper zookeeper
服務(wù)端deployer搭建
1、查詢數(shù)據(jù)源mysql服務(wù)的binlog位置
# 源mysql服務(wù)器中登陸mysql執(zhí)行
show binary logs;
image.png
直接在服務(wù)器上通過wget指令下載
wget https://github.com/alibaba/canal/releases/download/canal-1.1.6/canal.deployer-1.1.6.tar.gz
解壓安裝包
tar -zxvf canal.deployer-1.1.6.tar.gz
ElasticSearch是一個(gè)基于Lucene的搜索服務(wù)器,其實(shí)就是對Lucene進(jìn)行封裝,提供了 REST API 的操作接口. ElasticSearch作為一個(gè)高度可拓展的開源全文搜索和分析引擎,可用于快速地對大數(shù)據(jù)進(jìn)行存儲,搜索和分析。 ElasticSearch主要特點(diǎn):分布式、高可用、異步寫入、多API、面向文檔 。 ElasticSearch核心概念:近實(shí)時(shí),集群,節(jié)點(diǎn)(保存數(shù)據(jù)),索引,分片(將索引分片),副本(分片可設(shè)置多個(gè)副本) 。它可以快速地儲存、搜索和分析海量數(shù)據(jù)。 ElasticSearch使用案例:維基百科、Stack Overflow、Github 等等。
ElasticSearch集群安裝表格:
在安裝ElasticSearch之前,我們需要對Linux的環(huán)境做一些調(diào)整,防止在后續(xù)過程中出現(xiàn)一些問題!
1、修改最大內(nèi)存限制
修改sysctl.conf文件
vim /etc/sysctl.conf
在末尾增加如下配置:
vm.max_map_count = 655360
vm.swappiness=1
然后保存退出,輸入以下命令使其生效
sysctl -p
注:不同的linux服務(wù)器90-nproc.conf可能文件名不一樣,建議先在/etc/security/limits.d/查看文件名確認(rèn)之后再來進(jìn)行更改。
masternode的elasticsearch.yml文件配置如下:
cluster.name: xx
node.name: master
path.data: /home/elk/masternode/data
path.logs: /home/elk/masternode/logs
network.host: 0.0.0.0
network.publish_host: 192.169.0.23
transport.tcp.port: 9301
http.port: 9201
discovery.zen.ping.unicast.hosts: ["192.169.0.23:9301","192.169.0.24:9301","192.169.0.25:9301"]
node.master: true
node.data: false
node.ingest: false
index.number_of_shards: 5
index.number_of_replicas: 1
discovery.zen.minimum_master_nodes: 1
bootstrap.memory_lock: true
http.max_content_length: 1024mb
elasticsearch.yml文件參數(shù)配置說明:
將jvm.options配置Xms和Xmx改成2G,配置如下:
-Xms2g
-Xmx2g
將jvm.options配置Xms和Xmx改成8G,配置如下:
-Xms8g
-Xmx8g
談?wù)勲娚滔到y(tǒng)中的商品模塊設(shè)計(jì)
- product_detail 商品詳情
商品的詳情屬于存儲字符比較多,所以單獨(dú)處理,也可以利用這個(gè)表擴(kuò)展相關(guān)商品描述字段
- product_spec 商品規(guī)格表
- product_spec_item 商品屬性表
如何根據(jù)業(yè)務(wù)做出合適的商品模塊?
上面數(shù)據(jù)表只是設(shè)計(jì)的最基礎(chǔ)的商品的存儲,如果我們要設(shè)計(jì)出好的模塊,先要確定幾個(gè)點(diǎn):
- 平臺還是自營
- 現(xiàn)在和未來經(jīng)營的類目是標(biāo)品還是非標(biāo)品
- 公司經(jīng)營的商品種類
- 是否有分倉發(fā)貨業(yè)務(wù),庫存是否要綁定
電商自營和電商平臺的區(qū)別
電商自營,意味著所有的 item 和 sku 都是由己方的運(yùn)營控制,供貨商也穩(wěn)定為自營的一家,所以從常規(guī)意義上來說,電商平臺一定需要 SPU 的模塊,而自營電商不一定需要 SPU 模塊,例如某東。
SPU 主要是用來解決相同商品多 item 的規(guī)格和描述信息統(tǒng)一的問題,并且方便運(yùn)營做整個(gè)平臺的商品管理。后期的實(shí)際業(yè)務(wù)中,如果平臺運(yùn)營走的是類似天貓這樣對商家控制比較嚴(yán)格的路子,商家在進(jìn)行商品管理,也需要對商品可操作的 SPU 進(jìn)行授權(quán)管理,以及分潤比例控制。這些都是可以基于 SPU 進(jìn)行的。
經(jīng)營類目是標(biāo)品還是非標(biāo)品
如果加入了 SPU 的模塊,則需要了解經(jīng)營類目是標(biāo)品還是非標(biāo)品。如果是標(biāo)品,則可以在 SPU 層面加入 SPU 模版,以達(dá)到進(jìn)一步對商家可能發(fā)布的 SKU 的控制,確保平臺的商品可靠性。例:已知 iPhone X 只有 銀色64G、銀色256G、灰色64G、灰色256G這四種規(guī)格,那么平臺是可以在設(shè)置 iPhone X 的 SPU 時(shí),直接設(shè)置好 iPhone X下的這四個(gè)規(guī)格的屬性。這樣商家在創(chuàng)建時(shí)可以直接結(jié)用這四個(gè)屬性的信息進(jìn)行商品創(chuàng)建,規(guī)范了平臺商品的同時(shí)也達(dá)到了減少商家工作量的目的。
公司經(jīng)營的商品種類
這個(gè)一般不會對 SPU 和 SKU 的結(jié)構(gòu)關(guān)系造成影響,但是也是我們前期需要考慮的點(diǎn)。因?yàn)椴煌纳唐贩N類可能會對之后的交易訂單履約流程造成影響。簡要?dú)w納商品種類包含如下:
- 實(shí)物商品服務(wù)(打車,團(tuán)購)
- 虛擬資產(chǎn)(話費(fèi),游戲幣)
- 信息(卡密、簡歷、數(shù)據(jù))
一般電商平臺我們常見的商品種類主要還是實(shí)物商品和虛擬資產(chǎn),而服務(wù)類商品多見于線下 O2O 項(xiàng)目,信息類產(chǎn)品大多是垂直領(lǐng)域。所以如果可能涉及到多種類的商品交易,則需要在設(shè)計(jì) SPU 或 item 時(shí)就考慮到商品種類的設(shè)置。如果是在現(xiàn)有的系統(tǒng)基礎(chǔ)上去新增商品類型,其實(shí)也可以通過指定后臺類目商品類型的方式進(jìn)行后續(xù)的訂單履約業(yè)務(wù)。
Redis 集群結(jié)構(gòu)搭建
Redis集群架構(gòu)圖:
6000(master) 6003(slave)
6001(master) 6004(slave)
6002(master) 6005(slave)
image.png
MongoDB分為免費(fèi)社區(qū)版、收費(fèi)企業(yè)版,雖說前者功能有所閹割,但好在免費(fèi),并且可以滿足大多數(shù)項(xiàng)目需求,這里咱們先去MongoDB官網(wǎng)-社區(qū)版[4]選擇對應(yīng)的操作系統(tǒng)、版本下載安裝包,同Redis一樣,版本號的第二位數(shù),為奇數(shù)代表開發(fā)版,為偶數(shù)代表是穩(wěn)定版,我這里選擇下載CentOS7-x64-6.0.8-tgz版的安裝包。
?創(chuàng)建MongoDB目錄,并通過工具上傳安裝包至服務(wù)器(或虛擬機(jī)):
[root@~]# mkdir /soft && mkdir /soft/mongodb/
[root@~]# cd /soft/mongodb/
const categories = (function () {
let now = new Date();
let res = [];
let len = 10;
while (len--) {
res.unshift(now.toLocaleTimeString().replace(/^\D*/, ''));
now = new Date(+now - 2000);
}
return res;
})();
const categories2 = (function () {
let res = [];
let len = 10;
while (len--) {
res.push(10 - len - 1);
}
return res;
})();
const data: number[] = (function () {
let res = [];
let len = 10;
while (len--) {
res.push(Math.round(Math.random() * 1000));
}
return res;
})();
const data2: number[] = (function () {
let res = [];
let len = 0;
while (len < 10) {
res.push(+(Math.random() * 10 + 5).toFixed(1));
len++;
}
return res;
})();
option = {
title: {
text: 'Dynamic Data'
},
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'cross',
label: {
backgroundColor: '#283b56'
}
}
},
legend: {},
toolbox: {
show: true,
feature: {
dataView: { readOnly: false },
restore: {},
saveAsImage: {}
}
},
dataZoom: {
show: false,
start: 0,
end: 100
},
xAxis: [
{
type: 'category',
boundaryGap: true,
data: categories
},
{
type: 'category',
boundaryGap: true,
data: categories2
}
],
yAxis: [
{
type: 'value',
scale: true,
name: 'Price',
max: 30,
min: 0,
boundaryGap: [0.2, 0.2]
},
{
type: 'value',
scale: true,
name: 'Order',
max: 1200,
min: 0,
boundaryGap: [0.2, 0.2]
}
],
series: [
{
name: 'Dynamic Bar',
type: 'bar',
xAxisIndex: 1,
yAxisIndex: 1,
data: data
},
{
name: 'Dynamic Line',
type: 'line',
data: data2
}
]
};
app.count = 11;
setInterval(function () {
let axisData = new Date().toLocaleTimeString().replace(/^\D*/, '');
data.shift();
data.push(Math.round(Math.random() * 1000));
data2.shift();
data2.push(+(Math.random() * 10 + 5).toFixed(1));
categories.shift();
categories.push(axisData);
categories2.shift();
categories2.push(app.count++);
myChart.setOption<echarts.EChartsOption>({
xAxis: [
{
data: categories
},
{
data: categories2
}
],
series: [
{
data: data
},
{
data: data2
}
]
});
}, 2100);
image.png
MongoDB的數(shù)據(jù)存儲格式非常松散,采用“無模式、半結(jié)構(gòu)化”的思想,通過BSON格式來存儲數(shù)據(jù)。
[
BSON]的全稱為Binary JSON,翻譯過來是指二進(jìn)制的JSON格式,在存儲和掃描效率高于原始版JSON,但是對空間的占用會更高。
加群聯(lián)系作者vx:xiaoda0423
倉庫地址:https://github.com/webVueBlog/JavaGuideInterview
參考資料 [1]http://mongodb.github.io/mongo-java-driver/: https://link.juejin.cn?target=http%3A%2F%2Fmongodb.github.io%2Fmongo-java-driver%2F
[2]http://mongodb.github.io/mongo-java-driver/3.8/driver/getting-started/quick-start/: https://link.juejin.cn?target=http%3A%2F%2Fmongodb.github.io%2Fmongo-java-driver%2F3.8%2Fdriver%2Fgetting-started%2Fquick-start%2F
[3]https://projects.spring.io/spring-data-mongodb/: https://link.juejin.cn?target=https%3A%2F%2Fprojects.spring.io%2Fspring-data-mongodb%2F
[4]https://www.mongodb.com/try/download/community: https://link.juejin.cn?target=https%3A%2F%2Fwww.mongodb.com%2Ftry%2Fdownload%2Fcommunity
