Hologres RoaringBitmap在Lazada選品平臺的最佳實踐

Lazada選品平臺包含全網(wǎng)商家吱七、商品的圈選,通過Hologres RoaringBitmap能力幫助業(yè)務(wù)突破選品池20w大小限制伴挚,6000+選品池調(diào)度完成由12h下降至1h阎抒,單個選品池調(diào)度時間由90s下降至2s。

選品平臺介紹

Lazada選品平臺是面向內(nèi)部運營小二選品的操作系統(tǒng)司浪,其核心能力是:通過用戶制定的規(guī)則條件組合以篩選出滿足期望的業(yè)務(wù)實體泊业,這里的業(yè)務(wù)實體包括但不僅限于:商品、商家啊易。站在電商運營體系上來看吁伺,選品系統(tǒng)的核心職能在于 選 和 供,選出合適的 “品”(商品租谈、商家... )篮奄,供給到對應(yīng)的 “渠道” (會場、頻道割去、JFY...)窟却。通過供和選核心能力的組合,選品平臺在營銷活動鏈路中作為數(shù)據(jù)通路呻逆,打通從商家到消費者的核心鏈路夸赫,并且在導(dǎo)購鏈路賦能了會場、FlashSale咖城、JFY等等諸多業(yè)務(wù)茬腿,覆蓋了Lazada的絕大數(shù)場景化供給。

從選的角度來講宜雀,可以用于運營范圍圈定切平、業(yè)務(wù)準(zhǔn)入門檻、大促會場和日常頻道投放等辐董。在大促招商以及商家運營系統(tǒng)中悴品,商家范圍界定就成為整個運營流程的起點也是最值得關(guān)注的一點,限定滿足預(yù)期的商家會讓后續(xù)的流程更加順滑也勢必會取得更好的效果;在各種官方營銷活動中苔严,各行業(yè)運營會根據(jù)商家層級菇存、貨品類目、成交表現(xiàn)等為商家提供特定報名入口邦蜜,為消費者提供更匹配的貨品依鸥,選品成為不同層次門檻制定的有力抓手。從供的角度來講悼沈,多貨品集交并差供給贱迟、離線供給、打標(biāo)供給絮供、渠道供給等能力讓選品成為數(shù)據(jù)通路的統(tǒng)一出口衣吠。這里供給的含義不單純是將數(shù)據(jù)以在線或者離線的方式提供給下游,可能是一次打標(biāo)任務(wù)壤靶、一次 excel 導(dǎo)出缚俏、也可能是持續(xù)的增量打去標(biāo)任務(wù)。

Hologres(原交互式分析)是一站式實時數(shù)據(jù)倉庫引擎贮乳,支持海量數(shù)據(jù)實時寫入忧换、實時更新、實時分析向拆,支持標(biāo)準(zhǔn)SQL(兼容PostgreSQL協(xié)議)亚茬,支持PB級數(shù)據(jù)多維分析(OLAP)與自助分析(Ad Hoc),支持高并發(fā)低延遲的在線數(shù)據(jù)服務(wù)(Serving)浓恳,與MaxCompute刹缝、Flink、DataWorks深度融合颈将,提供離在線一體化全棧數(shù)倉解決方案梢夯。

在過去幾個月,我們把選品平臺的底層數(shù)據(jù)引擎從Ha3替換成Hologres晴圾,并使用DataWorks+Flink構(gòu)建了一套和Saro類似的離在線數(shù)據(jù)同步解決方案颂砸,打破了使用搜索引擎支撐選品的傳統(tǒng),開創(chuàng)了OLAP數(shù)據(jù)庫在選品平臺上應(yīng)用的先河疑务。

RoaringBitmap科普

Bitmap

在介紹RoaringBitmap之前沾凄,先來了解下Bitmap。

Bitmap的基本思想就是用一個bit位來標(biāo)記某個元素對應(yīng)的Value知允,而Key即是該元素。由于采用了Bit為單位來存儲數(shù)據(jù)叙谨,因此在存儲空間方面温鸽,可以大大節(jié)省。

假設(shè)有這樣一個需求:在20億個隨機整數(shù)中找出某個數(shù)m是否存在其中,并假設(shè)32位操作系統(tǒng)涤垫,4G內(nèi)存

在Java中姑尺,int占4字節(jié),1字節(jié)=8位(1 byte = 8 bit)

如果每個數(shù)字用int存儲蝠猬,那就是20億個int切蟋,因而占用的空間約為 (2000000000*4/1024/1024/1024)≈7.45G

如果按位存儲就不一樣了,20億個數(shù)就是20億位榆芦,占用空間約為 (2000000000/8/1024/1024/1024)≈0.233G

假設(shè)有四個整數(shù):int[ ] a = { 0, 3, 5, 7 }柄粹,使用下圖的Bitmap表示,表格標(biāo)記了0到7的數(shù)字匆绣,其中0驻右、3、5和7被標(biāo)記為1:

因為1Int = 4Byte = 32Bit崎淳,所以一個Int所占的二進(jìn)制位可以映射32個數(shù)字堪夭,相當(dāng)于壓縮了32倍,那么之前20億個整數(shù)所需要的7.45GB內(nèi)存可縮減至233.41MB拣凹。

Bitmap的問題在于森爽,不管業(yè)務(wù)中實際的元素基數(shù)有多少,它占用的內(nèi)存空間都恒定不變嚣镜。如果Bitmap中的位的取值范圍是1到100億之間拗秘,那么Bitmap就會開辟出100億Bit的存儲空間。但是如果實際上值只有100個的話祈惶,100億Bit的存儲空間只有100個Bit為1雕旨,其余全部為0,數(shù)據(jù)存儲空間浪費嚴(yán)重捧请,數(shù)據(jù)越稀疏凡涩,空間浪費越嚴(yán)重。

RoaringBitmap

為了解決Bitmap稀疏存儲浪費空間的問題疹蛉,出現(xiàn)了很多稀疏位圖的壓縮算法活箕,RoaringBitmap就是其中的優(yōu)秀代表。

RoaringBitmap是高效壓縮位圖可款,簡稱RBM育韩。RBM的歷史并不長,它于2016年由S. Chambi闺鲸、D. Lemire筋讨、O. Kaser等人在論文《Better bitmap performance with Roaring bitmaps》與《Consistently faster and smaller compressed bitmaps with Roaring》中提出。

RoaringBitMap的基本思路:

將數(shù)據(jù)的前半部分摸恍,即高16位作為桶的編號悉罕,分為65536個桶赤屋,RBM中將這些小桶稱之為Contriner(容器)

存儲數(shù)據(jù)時,按照數(shù)據(jù)的高16位做為Contriner的編號去找對應(yīng)的Contriner(找不到就創(chuàng)建對應(yīng)的Contriner)壁袄,再將低16位放入該Contriner中:

與Bitmap相比的優(yōu)勢

●空間節(jié)世嘣纭:Bitmap比較適用于數(shù)據(jù)分布比較稠密的存儲場景中;RoarringBitMap在稀疏存儲上空間更省嗜逻,稠密和Bitmap一致涩僻。

●更高效的做交、并操作:將大塊的Bitmap分成各個小塊栈顷,其中每個小塊在需要存儲數(shù)據(jù)的時候才會存在逆日。所以當(dāng)進(jìn)行交集或并集運算的時候,只需要去計算存在的一些塊妨蛹,而不需要像Bitmap那樣對整個大的塊進(jìn)行計算屏富。這里既不是用空間換時間,也沒有用時間換空間蛙卤,而是用邏輯的復(fù)雜度同時換取了空間和時間狠半。

集合運算性能下面這段代碼測試RoaringBitmap與數(shù)組在交集運算上的性能差異:

RoaringBitmap rbAnd1 = new RoaringBitmap();for (int k = 100000; k < 200000; k++) {    rbAnd1.add(k);}
RoaringBitmap rbAnd2 = new RoaringBitmap();for (int k = 150000; k < 200000; k++) {    rbAnd2.add(k);}
Long start = System.currentTimeMillis();rbAnd1.and(rbAnd2);System.out.println("roaringBitmap and 耗時:" + (System.currentTimeMillis() - start) + "ms");

List<Integer> list1 = new ArrayList<>();for (int k = 100000; k < 200000; k++) {    list1.add(k);}
List<Integer> list2 = new ArrayList<>();for (int k = 150000; k < 200000; k++) {    list2.add(k);}
start = System.currentTimeMillis();list1.retainAll(list2);System.out.println("list and 耗時:" + (System.currentTimeMillis() - start) + "ms");

測試結(jié)果:

roaringBitmap and 耗時:1ms
list and 耗時:3056ms

下面這段代碼測試RoaringBitmap與數(shù)組在差集運算上的性能差異:

RoaringBitmap rbAnd1 = new RoaringBitmap();for (int k = 100000; k < 200000; k++) {    rbAnd1.add(k);}
RoaringBitmap rbAnd2 = new RoaringBitmap();for (int k = 150000; k < 200000; k++) {    rbAnd2.add(k);}
Long start = System.currentTimeMillis();rbAnd1.andNot(rbAnd2);System.out.println("roaringBitmap andNot 耗時:" + (System.currentTimeMillis() - start) + "ms");

List<Integer> list1 = new ArrayList<>();for (int k = 100000; k < 200000; k++) {    list1.add(k);}
List<Integer> list2 = new ArrayList<>();for (int k = 150000; k < 200000; k++) {    list2.add(k);}
start = System.currentTimeMillis();list1.removeAll(list2);System.out.println("list andNot 耗時:" + (System.currentTimeMillis() - start) + "ms");

測試結(jié)果:

roaringBitmap andNot 耗時:1ms
list andNot 耗時:3350ms

從測試結(jié)果不難看出,在集合傳統(tǒng)的交差集運算上颤难,RoaringBitmap具有無與倫比的速度優(yōu)勢神年。

RoaringBitmap實踐

指標(biāo)存儲

前文提到我們把選品平臺的底層數(shù)據(jù)引擎升級成Hologres,Hologres數(shù)倉存儲了lazada全平臺的商品行嗤,按目前運營小二組合商品表現(xiàn)數(shù)據(jù)來選品的習(xí)慣已日,我們把商品的表現(xiàn)數(shù)據(jù)抽象成商品指標(biāo)存儲在大寬表(為什么叫大寬表,因為隨著業(yè)務(wù)關(guān)注視角的不同栅屏,指標(biāo)越來越多飘千,目前已經(jīng)接近300個字段)。

其中商品指標(biāo)不乏多值字段栈雳,如:商品所屬類目护奈、商品已報名活動、商品所屬行業(yè)...哥纫,存儲這些多值字段霉旗,我們一開始采用數(shù)組類型字段進(jìn)行存儲。如果運營小二使用了多值指標(biāo)進(jìn)行選品蛀骇,規(guī)則翻譯模塊會把運營的輸入翻譯成數(shù)組的交集運算提交到Hologres執(zhí)行厌秒。直到我們從Hologres的監(jiān)控發(fā)現(xiàn),CPU偶有沖高到100%的情況:

通過抓取該段時間的慢SQL擅憔,我們發(fā)現(xiàn)導(dǎo)致CPU沖高的大部分SQL都是數(shù)組取交集的運算鸵闪。

問題定位到了,當(dāng)時想到兩種優(yōu)化方案:

●多值字段從數(shù)組換成RoaringBitmap雕欺,RoaringBitmap是一種高效的Bitmap壓縮算法岛马,目前已被廣泛應(yīng)用在各種語言和各種大數(shù)據(jù)平臺棉姐。適合計算超高基維的屠列,常用于去重啦逆、標(biāo)簽篩選、時間序列等計算中笛洛。

●多值字段依舊使用數(shù)組夏志,數(shù)據(jù)落表時先排好序再寫入,在查詢?nèi)〗患瘯r苛让,傳入比較的數(shù)組也排好序沟蔑,即“先排序再比較”的策略。

兩種優(yōu)化方案優(yōu)劣比較:

離線寫入:即商品大寬表數(shù)據(jù)由MaxCompute寫入到Hologres狱杰,選品平臺的數(shù)據(jù)層一般由離線數(shù)據(jù)和在線數(shù)據(jù)兩部分組成

綜上瘦材,字段類型修改為RoaringBitmap,離線寫入的耗時增加1min左右 CPU消耗增加10%仿畸,對離線鏈路構(gòu)建時長的影響可以忽略食棕;查詢性能大幅優(yōu)于有序的數(shù)組和現(xiàn)有無序的數(shù)組。

基于此错沽,我們把商品大寬表的23個多值字段由數(shù)組類型升級成RoaringBitmap簿晓,整體優(yōu)化收益如下:

●商品大寬表存儲空間下降30% ~ 40%,存儲文件個數(shù)下降30% ~ 40%(不同國家有所差異千埃,整體在30% ~ 40%)憔儿。文件個數(shù)減少有以下幾個好處:

○提高查詢性能:更少的文件意味著查詢需要掃描的數(shù)據(jù)量和文件數(shù)量都較少,從而提高查詢速度和系統(tǒng)整體性能放可。

○減少存儲開銷:小文件會在硬盤上產(chǎn)生更多的碎片谒臼,導(dǎo)致磁盤空間利用率降低,文件個數(shù)減少有助于提高磁盤空間利用率耀里。

○簡化管理:當(dāng)文件數(shù)量較多時蜈缤,管理和監(jiān)控任務(wù)會變得更加復(fù)雜。文件個數(shù)減少能夠簡化管理和維護(hù)工作备韧,提高運維效率劫樟。

○優(yōu)化備份和恢復(fù):備份大量小文件通常比備份少量大文件所需的時間更長。文件個數(shù)減少可以縮短備份和恢復(fù)的時間织堂,提高業(yè)務(wù)連續(xù)性叠艳。

○減輕元數(shù)據(jù)壓力:文件系統(tǒng)需要跟蹤每個文件的信息(如權(quán)限、大小等)易阳,大量的小文件會增加元數(shù)據(jù)的壓力附较。文件個數(shù)減少有助于減輕元數(shù)據(jù)服務(wù)器的壓力,保證系統(tǒng)的穩(wěn)定運行潦俺。

●Hologres CPU利用率下降30%

HologresRoaringBitmap類型字段建表語句參考:

BEGIN;

CREATE TABLE public.test (
    product_id bigint NOT NULL,
    product_categories roaringbitmap,
    ds text NOT NULL,
    PRIMARY KEY (product_id, ds)
) PARTITION BY LIST (ds);

CALL set_table_property('public.test', 'orientation', 'column,row');
CALL set_table_property('public.test', 'distribution_key', 'product_id');

END;

選品池運算

選品池:符合運營小二選品規(guī)則的業(yè)務(wù)實體(商品拒课、商家...)的集合徐勃,選品池數(shù)據(jù)一般為商品ID或商家ID的集合

“供給”是選品平臺的核心能力,圍繞著“供給”早像,我們構(gòu)建了選品池持續(xù)的增量打標(biāo)/去標(biāo)的核心能力僻肖。打標(biāo)供給核心流程如下:

當(dāng)前打標(biāo)供給流程核心問題定義:

●數(shù)據(jù)冗余:因為需要對選品池今天和昨天的數(shù)據(jù)進(jìn)行比較,選品池今天的數(shù)據(jù)從選品引擎實時拉取卢鹦,選品池昨天的數(shù)據(jù)冗余到Mysql以方便第二天進(jìn)行比較

●選品池運算:今天和昨天的選品池數(shù)據(jù)對比臀脏,在應(yīng)用內(nèi)存中進(jìn)行,如果選品池數(shù)據(jù)量過大冀自,容易觸發(fā)應(yīng)用頻繁的FullGC揉稚。技術(shù)通過設(shè)置20w上限來規(guī)避這個問題,業(yè)務(wù)對突破20w的述求越來越強烈

●調(diào)度效率低:6000+選品池調(diào)度完成熬粗,要12h搀玖,單個選品池調(diào)度完成花費80~90s

在了解到RoaringBitmap在集合存儲具有較大的空間優(yōu)勢,在集合運算具有較大的時間優(yōu)勢驻呐,我們決定使用RoaringBitmap來存儲選品池數(shù)據(jù)灌诅。

在RoaringBitmap落地過程中,遇到了很多困難和挑戰(zhàn)暴氏,羅列其中一二:

●為了解決數(shù)據(jù)冗余的問題延塑,我們限定選品池數(shù)據(jù)不出Hologres數(shù)倉,也就是要借助Hologres的RoaringBitmap字段類型來存儲選品池數(shù)據(jù)答渔。但Hologres的RoaringBitmap字段類型只支持32位整數(shù)存儲关带,商品ID和商家ID顯然已經(jīng)超過了32位整數(shù)的范圍。于是沼撕,問題就演化成了RoaringBitmap怎么能存下64位整數(shù)宋雏。從實現(xiàn)復(fù)雜度,以及對未來SKU選品池支撐友好程度等多方面綜合考慮务豺,我們最終采用分桶法磨总。

○偏移法:

○分桶法:將商品ID或商家ID拆為低位和桶號,這里我們直接將商品ID的高34位作為桶號笼沥,將低30位存入RoaringBitmap

○自定義id:因為商品ID或商家ID均存在較大的斷層蚪燕,實際上商品數(shù)量和商家數(shù)量遠(yuǎn)未達(dá)到32位整數(shù)的上限,內(nèi)部維護(hù)一個自增長ID去映射商品ID或商家ID

在攻克了諸多困難和挑戰(zhàn)后奔浅,打標(biāo)供給整體實現(xiàn)方案簡化為如下流程:

選品池運算核心邏輯:

優(yōu)化整體收益:

●數(shù)據(jù)流轉(zhuǎn)效率:6000+選品池調(diào)度完成由12h下降至1h馆纳,單個選品池調(diào)度時間由90s下降至2s

●系統(tǒng)穩(wěn)定性:應(yīng)用層FullGC次數(shù)下降88%

●存儲成本:消除數(shù)據(jù)冗余,節(jié)省75GB存儲空間

●業(yè)務(wù)突破:幫助業(yè)務(wù)突破選品池20w大小限制汹桦,目前暫定50w

Hologres RoaringBitmap分桶表建表語句參考:


CREATE TABLE public.test_pool_dump_rb (
    pool_id bigint NOT NULL,
    pool_type text NOT NULL,
    bucket bigint NOT NULL,
    pool_data roaringbitmap NOT NULL,
    ext text NOT NULL,
    ds text NOT NULL
    ,PRIMARY KEY (pool_id, bucket, ds)
)
  PARTITION BY LIST (ds);

CALL set_table_property('public.test_pool_dump_rb', 'orientation', 'column,row');
CALL set_table_property('public.test_pool_dump_rb', 'clustering_key', 'pool_id:asc');
CALL set_table_property('public.test_pool_dump_rb', 'distribution_key', 'pool_id');
CALL set_table_property('public.test_pool_dump_rb', 'table_storage_mode', 'any');
CALL set_table_property('public.test_pool_dump_rb', 'auto_partitioning.enable', 'true');
CALL set_table_property('public.test_pool_dump_rb', 'auto_partitioning.time_unit', 'day');
CALL set_table_property('public.test_pool_dump_rb', 'auto_partitioning.time_zone', 'ASIA/SHANGHAI');
CALL set_table_property('public.test_pool_dump_rb', 'auto_partitioning.num_precreate', '2');
CALL set_table_property('public.test_pool_dump_rb', 'auto_partitioning.num_retention', '2');
CALL set_table_property('public.test_pool_dump_rb', 'auto_partitioning.num_hot', '-1');

END;

導(dǎo)出選品池數(shù)據(jù)到RoaringBitmap SQL參考:

insert into test_pool_dump_rb_${ds}
(pool_id, pool_type, bucket, pool_data, ext, ds)
select
#{poolId} as pool_id,
#{poolType} as pool_type,
product_id >> 30 as bucket,
rb_build(array_agg(${product_id} <![CDATA[&]]> 1073741823)) as pool_data,
#{ext} as ext,
#{ds} as ds
from (
    select product_id from test
) A
group by product_id >> 30

選品池差集運算SQL參考:

select A.pool_id, A.pool_type, A.bucket, rb_to_array(A.pool_data - if(B.pool_data is null, rb_build('{}'), B.pool_data)) as pool_data
from
(
    select pool_id, pool_type, bucket, pool_data
    from test_pool_dump_rb
    where pool_id = #{poolId}
    and ds = #{ds}
) A left join
(
    select pool_id, bucket, pool_data
    from test_pool_dump_rb
    where pool_id = #{poolId}
    and ds = #{differenceDs}
) B on A.pool_id = B.pool_id and A.bucket = B.bucket

總 結(jié)

RoaringBitmap的成功應(yīng)用鲁驶,不僅是對業(yè)務(wù)功能的強力助推,彰顯了技術(shù)對業(yè)務(wù)突破的關(guān)鍵賦能作用舞骆,更是先進(jìn)技術(shù)驅(qū)動生產(chǎn)效率提升的典范钥弯。RoaringBitmap通過其高效的壓縮機制大幅優(yōu)化數(shù)據(jù)存儲(空間效率)径荔,以及卓越的集合處理能力顯著提高操作性能(時間效率),有效克服了業(yè)務(wù)在選品池規(guī)模上的原有約束脆霎,實現(xiàn)了對20萬條數(shù)據(jù)容量限制的突破总处。這不僅證明了RoaringBitmap技術(shù)的先進(jìn)性,也是技術(shù)創(chuàng)新提升核心競爭力的生動實例绪穆。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末辨泳,一起剝皮案震驚了整個濱河市虱岂,隨后出現(xiàn)的幾起案子玖院,更是在濱河造成了極大的恐慌,老刑警劉巖第岖,帶你破解...
    沈念sama閱讀 216,372評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件难菌,死亡現(xiàn)場離奇詭異,居然都是意外死亡蔑滓,警方通過查閱死者的電腦和手機郊酒,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來键袱,“玉大人燎窘,你說我怎么就攤上這事√憧В” “怎么了褐健?”我有些...
    開封第一講書人閱讀 162,415評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長澜汤。 經(jīng)常有香客問我蚜迅,道長,這世上最難降的妖魔是什么俊抵? 我笑而不...
    開封第一講書人閱讀 58,157評論 1 292
  • 正文 為了忘掉前任谁不,我火速辦了婚禮,結(jié)果婚禮上徽诲,老公的妹妹穿的比我還像新娘刹帕。我一直安慰自己,他們只是感情好谎替,可當(dāng)我...
    茶點故事閱讀 67,171評論 6 388
  • 文/花漫 我一把揭開白布偷溺。 她就那樣靜靜地躺著,像睡著了一般院喜。 火紅的嫁衣襯著肌膚如雪亡蓉。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,125評論 1 297
  • 那天喷舀,我揣著相機與錄音砍濒,去河邊找鬼淋肾。 笑死,一個胖子當(dāng)著我的面吹牛爸邢,可吹牛的內(nèi)容都是我干的樊卓。 我是一名探鬼主播,決...
    沈念sama閱讀 40,028評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼杠河,長吁一口氣:“原來是場噩夢啊……” “哼碌尔!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起券敌,我...
    開封第一講書人閱讀 38,887評論 0 274
  • 序言:老撾萬榮一對情侶失蹤唾戚,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后待诅,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體叹坦,經(jīng)...
    沈念sama閱讀 45,310評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,533評論 2 332
  • 正文 我和宋清朗相戀三年卑雁,在試婚紗的時候發(fā)現(xiàn)自己被綠了募书。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,690評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡测蹲,死狀恐怖莹捡,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情扣甲,我是刑警寧澤篮赢,帶...
    沈念sama閱讀 35,411評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站文捶,受9級特大地震影響荷逞,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜粹排,卻給世界環(huán)境...
    茶點故事閱讀 41,004評論 3 325
  • 文/蒙蒙 一种远、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧顽耳,春花似錦坠敷、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至胰耗,卻和暖如春限次,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評論 1 268
  • 我被黑心中介騙來泰國打工卖漫, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留费尽,地道東北人。 一個月前我還...
    沈念sama閱讀 47,693評論 2 368
  • 正文 我出身青樓羊始,卻偏偏與公主長得像旱幼,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子突委,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,577評論 2 353

推薦閱讀更多精彩內(nèi)容