±à¼ÍƼö: |
±¾ÎÄÖ÷Òª½éÉÜÁËÊÂÎñÃèÊö¡¢
redisÊÂÎñ´¦Àí¡¢redisÊÂÎñʾÀý¡¢redis³Ö¾Ã»¯¡£
±¾ÎÄÀ´×Ô²©¿ÍÔ°£¬ÓÉ»ðÁú¹ûÈí¼þAnna±à¼¡¢ÍƼö¡£
|
|
1. ÊÂÎñÃèÊö £¨1£©Ê²Ã´ÊÇÊÂÎñ
ÊÂÎñ£¬¾ÍÊǰÑÒ»¶ÑÊÂÇé°óÔÚÒ»Æð£¬°´Ë³ÐòµÄÖ´ÐУ¬¶¼³É¹¦Á˲ÅËãÍê³É£¬·ñÔò»Ö¸´Ö®Ç°µÄÑù×Ó
ÊÂÎñ±ØÐë·þ´ÓACIDÔÔò£¬ACIDÔÔò·Ö±ðÊÇÔ×ÓÐÔ£¨atomicity£©¡¢Ò»ÖÂÐÔ£¨consistency£©¡¢¸ôÀëÐÔ£¨isolation£©ºÍ³Ö¾ÃÐÔ£¨durability£©
Ô×ÓÐÔ£º²Ù×÷ÕâЩָÁîʱ£¬ÒªÃ´È«²¿Ö´Ðгɹ¦£¬ÒªÃ´È«²¿²»Ö´ÐС£Ö»ÒªÆäÖÐÒ»¸öÖ¸ÁîÖ´ÐÐʧ°Ü£¬ËùÓеÄÖ¸Áî¶¼Ö´ÐÐʧ°Ü£¬Êý¾Ý½øÐлعö£¬»Øµ½Ö´ÐÐÖ¸ÁîǰµÄÊý¾Ý״̬
Ò»ÖÂÐÔ£ºÊÂÎñµÄÖ´ÐÐʹÊý¾Ý´ÓÒ»¸ö״̬ת»»ÎªÁíÒ»¸ö״̬£¬µ«ÊǶÔÓÚÕû¸öÊý¾ÝµÄÍêÕûÐÔ±£³ÖÎȶ¨
¸ôÀëÐÔ£ºÔÚ¸ÃÊÂÎñÖ´ÐеĹý³ÌÖУ¬ÎÞÂÛ·¢ÉúµÄÈκÎÊý¾ÝµÄ¸Ä±ä¶¼Ó¦¸ÃÖ»´æÔÚÓÚ¸ÃÊÂÎñÖ®ÖУ¬¶ÔÍâ½ç²»´æÔÚÓ°Ï죬ֻÓÐÔÚÊÂÎñÈ·ÈÏÌá½»Ö®ºóÃDzŻáÏÔʾ¸ÃÊÂÎñ¶ÔÊý¾ÝµÄ¸Ä±ä£¬ÆäËûÊÂÎñ²ÅÄÜ»ñÈ¡µ½ÕâЩ¸Ä±äºóµÄÊý¾Ý
³Ö¾ÃÐÔ£ºµ±ÊÂÎñÕýÈ·Íê³Éºó£¬Ëü¶ÔÓÚÊý¾ÝµÄ¸Ä±äÊÇÓÀ¾ÃÐÔµÄ
£¨2£©²¢·¢ÊÂÎñµ¼Öµij£¼û´íÎó
µÚÒ»Àඪʧ¸üУº³·ÏúÒ»¸öÊÂÎñʱ£¬°ÑÆäËûÊÂÎñÒÑÌá½»µÄ¸üÐÂÊý¾Ý¸²¸Ç
Ôà¶Á£ºÒ»¸öÊÂÎñ¶ÁÈ¡µ½ÁíÒ»¸öÊÂÎñδÌá½»µÄ¸üÐÂÊý¾Ý
»Ã¶ÁÒ²½ÐÐé¶Á£ºÒ»¸öÊÂÎñÖ´ÐÐÁ½´Î²éѯ£¬µÚ¶þ´Î½á¹û¼¯°üº¬µÚÒ»´ÎÖÐûÓлòijЩÐÐÒѾ±»É¾³ýµÄÊý¾Ý£¬Ôì³ÉÁ½´Î½á¹û²»Ò»Ö£¬Ö»ÊÇÁíÒ»¸öÊÂÎñÔÚÕâÁ½´Î²éѯÖмä²åÈë»òɾ³ýÁËÊý¾ÝÔì³ÉµÄ
²»¿ÉÖØ¸´¶Á£ºÒ»¸öÊÂÎñÁ½´Î¶ÁȡͬһÐеÄÊý¾Ý£¬½á¹ûµÃµ½²»Í¬×´Ì¬µÄ½á¹û£¬ÖмäÕýºÃÁíÒ»¸öÊÂÎñ¸üÐÂÁ˸ÃÊý¾Ý£¬Á½´Î½á¹ûÏàÒ죬²»¿É±»ÐÅÈÎ
µÚ¶þÀඪʧ¸üУºÊDz»¿ÉÖØ¸´¶ÁµÄÌØÊâÇé¿ö¡£Èç¹ûÁ½¸öÊÂÎï¶¼¶ÁȡͬһÐУ¬È»ºóÁ½¸ö¶¼½øÐÐд²Ù×÷£¬²¢Ìá½»£¬µÚÒ»¸öÊÂÎïËù×öµÄ¸Ä±ä¾Í»á¶ªÊ§
2. redisÊÂÎñ´¦Àí redisÊÂÎñͨ¹ýMULTI¡¢WATCH¡¢UNWAYCH¡¢EXEC¡¢DISCARDÎå¸öÃüÁîʵÏÖ
MUTILÃüÁÓÃÓÚ¿ªÆôÒ»¸öÊÂÎñ£¬¿Í»§¶Ë¿ÉÒÔ¼ÌÐøÏò·þÎñÆ÷·¢ËÍÈÎÒâ¶àÌõÃüÁÕâЩÃüÁî²»»áÁ¢¼´±»Ö´ÐУ¬¶øÊDZ»·Åµ½Ò»¸ö¶ÓÁÐÖУ¬µ±EXECÃüÁî±»µ÷ÓÃʱ£¬ËùÓжÓÁÐÖеÄÃüÁî²Å»á±»Ö´ÐУ¬Ëü×ÜÊÇ·µ»ØOK
WATCHÃüÁ¶Ô¼ü½øÐмàÊÓ£¬Ö±µ½Óû§Ö´ÐÐEXECÃüÁîµÄÕâ¶Îʱ¼äÀïÃæ£¬Èç¹ûÆäËû¿Í»§¶ËÇÀÏȶÔÈκα»¼àÊӵļü½øÐÐÁËÌæ»»¡¢¸üлòɾ³ýµÈ²Ù×÷£¬ÄÇôµ±Óû§²ÕÊÒÖ´ÐÐEXECÃüÁîµÄʱºò£¬ÊÂÎñ½«Ê§°Ü²¢·µ»ØÒ»¸ö´íÎó£¨Ö®ºóÓû§¿ÉÒÔÑ¡ÔñÖØÊÔ»òÕß·ÅÆúÊÂÎñ£©
UNWATCHÃüÁÔÚWATCHÃüÁîÖ´ÐÐÖ®ºó£¬EXECÃüÁîÖ´ÐÐ֮ǰ¶ÔÁ´½Ó½øÐÐÖØÖÃ
EXECÃüÁִÐÐÊÂÎñÃüÁî
DISCARDÃüÁ¿Í»§¶Ë¿ÉÒÔÈ¡ÏûWATCHÃüÁîÃûÇå¿ÕËùÓÐÒÑÈë¶ÓÃüÁî
3. redisÊÂÎñʾÀý ÏÂÃæ½«ÓÃÉÌÆ·½»Ò×ʾÀý˵Ã÷ÊÂÎñ´¦Àí¹ý³Ì

£¨1£©½«ÉÌÆ·Í¶·Åµ½Êг¡
a. ʹÓÃÉ¢ÁУ¨users:£©À´¹ÜÀíÊг¡ÖеÄËùÓÐÓû§ÐÅÏ¢£¬°üÀ¨Óû§Ãû¡¢Óû§ÓµÓеÄÇ®

b. ʹÓü¯ºÏ£¨inventory:£©À´¹ÜÀíÿ¸öÓû§µÄËùÓÐÉÌÆ·ÐÅÏ¢£¬°üÀ¨ÉÌÆ·ÃûÃû

inventory:1¶ÔÓ¦Óû§User:1µÄ±¨¸æ
c. ʹÓÃÓÐÐò¼¯ºÏ£¨market:£©À´¹ÜÀíͶ·Åµ½Êг¡ÖеÄÉÌÆ·
Á÷³Ì£º¼ì²éinventory:1°ü¹üÖÐÊÇ·ñº¬ÓÐItemLÉÌÆ·----->½«inventory:1°ü¹üÖеÄItemLÉÌÆ·Ìí¼Óµ½½»Ò×Êг¡----->ɾ³ýinventory:1°ü¹üÖеÄItemLÉÌÆ·
def list_item(conn,userid,goodsname,price):
#ʹÓÃÓÐÐò¼¯ºÏ£¨market:£©À´¹ÜÀíͶ·Åµ½Êг¡ÖеÄÉÌÆ·
#ÉÌÆ·µÄkeyΪuserid:goodsid
inventory = 'inventory:%s' %(userid)
user = 'User:%s' %(userid)
goodsitem = '%s:%s' %(userid,goodsname)
end = time.time() + 5
pipe = conn.pipeline()
while time.time() < end:
try:
pipe.watch(inventory) #¼àÊÓ°ü¹ü·¢ÉúµÄ±ä»¯
if not pipe.sismember(inventory,goodsname): #¼ì²éÓû§ÊÇ·ñÈÔÈ»³ÖÓн«Òª±»·ÅÈëÊг¡µÄÉÌÆ·
pipe.unwatch()
return None
pipe.multi()
pipe.zadd('market:',{goodsitem:price}) #½«ÉÌÆ·Í¶·Åµ½Êг¡
pipe.srem(inventory, goodsname) #´ÓÓû§°ü¹üÖÐɾ³ý¸ÃÉÌÆ·
pipe.execute()
print('É̳¡ÖеÄÉÌÆ·£º',conn.zrange('market:', 0, -1,withscores=True))
print('ÉÌÆ·Í¶·ÅÊг¡ºóÓû§{} µÄÉÌÆ·£º{}'.format (userid, conn.smembers(inventory)))
return True
except redis.exceptions.WatchError as e:
print(e)
return False |
²âÊÔ£º

£¨2£©½»Ò×£ºUser:2¹ºÂò½»Ò×Êг¡ÖеÄÖеÄItemLÉÌÆ·
˼Ï룺ʹÓÃwatch¶ÔÊг¡ÒÔ¼°Âò¼ÒµÄ¸öÈËÐÅÏ¢½øÐмàÊÓ£¬È»ºó»ñÈ¡Âò¼ÒÓµÓеÄÇ®ÊýÒÔ¼°ÉÌÆ·Êг¡µÄÊÛ¼Û£¬²¢¼ì²éÂò¼ÒÊÇ·ñÓÐ×ã¹»µÄÇ®À´¹ºÂòÉÌÆ·£¬Èç¹ûÂò¼ÒûÓÐ×ã¹»µÄÇ®£¬ÄÇô³ÌÐò»áÈ¡ÏûÊÂÎñ£¬Èç¹ûÂò¼ÒÇ®×ã¹»£¬ÄÇô³ÌÐòÊ×ÏȻὫÂò¼ÒÖ§¸¶µÄÇ®×ªÒÆ¸øÂô¼Ò£¬È»ºó½«ÊÛ³öµÄÉÌÆ·ÒƳýÉÌÆ·½»Ò×Êг¡¡£
def purchase_item(conn,
buyerid, goodsname, sellerid):
buyer = 'User:{}'.format(buyerid) #Âò¼Òkey
seller = 'User:{}'.format(sellerid) #Âô¼Òkey
buy_inventory = 'inventory:{}'.format(buyerid)
#Âò¼Ò°ü¹ükey
sell_inverntory = 'inventory:{}'.format(sellerid)
#Âô¼Ò°ü¹ükey
goodsitem = '{}:{ }'.format(sellerid,goodsname)
#Êг¡ÖеÄÉÌÆ·key
end = time.time() + 5
pipe = conn.pipeline()
while time.time() < end:
try:
pipe.watch('market:',buyer) #¶ÔÉÌÆ·ÂòÂôÊг¡ÒÔ¼°Âò¼ÒµÄ¸öÈËÐÅÏ¢½øÐмàÊÓ
funds = int(pipe.hget(buyer,'funds')) #µÃµ½Âò¼ÒÓµÓеÄÇ®
print('Âò¼ÒÊÖÉϵÄÇ®£º', funds)
price = pipe.zscore('market:', goodsitem) #µÃµ½ÉÌÆ·µÄ¼Û¸ñ
print('price:',price)
if funds < price:
pipe.unwatch()
return None
pipe.multi()
pipe.hincrby(buyer, 'funds', int(-price)) #Âò¼ÒµÄÇ®¼õÉÙ
pipe.hincrby(seller, 'funds', int(price)) #Âô¼ÒµÄÇ®Ôö¼Ó
pipe.sadd(buy_inventory,goodsname)
pipe.zrem('market:', goodsitem)
pipe.execute()
print('½»Ò×Êг¡ÖеÄÉÌÆ·£º', conn.zrange('market:', 0, -1,
withscores=True))
print('Âò¼ÒÏÖÔÚÊÖÖеÄÇ®£º',conn.hget(buyer, 'funds'))
print('Âò¼Ò°ü¹üÄÚÈÝ£º', conn.smembers(buy_inventory))
print('Âô¼ÒÏÖÔÚÊÖÖеÄÇ®£º',conn.hget(seller, 'funds'))
return True
except redis.exceptions.WatchError as e:
print(e)
return False |
²âÊÔ£º
if __name__
== '__main__':
conn = redis.Redis()
#create_users(conn)
#create_user_inventory(conn)
list_item(conn,1,'ItemL',28)
purchase_item(conn, 2, 'ItemL', 1) |

4. redis³Ö¾Ã»¯ redisÌṩÁËÁ½ÖÖ²»Í¬µÄ³Ö¾Ã»¯·½Ê½À´½«Êý¾Ý´ÓÄÚ´æ´æ´¢µ½Ó²ÅÌÀïÃæ£¬Ò»ÖÖÊÇRDB³Ö¾Ã»¯£¬ÔÀíÊǽ«redisÄÚ´æÖеÄÊý¾Ý¿â¼Ç¼¶¨Ê±dumpµ½´ÅÅÌÉϵÄRDB³Ö¾Ã»¯£¬ÁíÍâÒ»ÖÖÊÇAOF(append
only file)³Ö¾Ã»¯£¬ÔÀíÊDZ»Ö´ÐеÄдÃüÁî¸´ÖÆµ½´ÅÅÌÀï¡£
£¨1£©RDB³Ö¾Ã»¯ÅäÖÃ
# Save the DB
on disk:
# ÉèÖÃsedis½øÐÐÊý¾Ý¿â¾µÏñµÄƵÂÊ¡£
# 900Ã루15·ÖÖÓ£©ÄÚÖÁÉÙ1¸ökeyÖµ¸Ä±ä£¨Ôò½øÐÐÊý¾Ý¿â±£´æ--³Ö¾Ã»¯£©¡£
# 300Ã루5·ÖÖÓ£©ÄÚÖÁÉÙ10¸ökeyÖµ¸Ä±ä£¨Ôò½øÐÐÊý¾Ý¿â±£´æ--³Ö¾Ã»¯£©¡£
# 60Ã루1·ÖÖÓ£©ÄÚÖÁÉÙ10000¸ökeyÖµ¸Ä±ä£¨Ôò½øÐÐÊý¾Ý¿â±£´æ--³Ö¾Ã»¯£©¡£
save 900 1
save 300 10
save 60 10000
stop-writes-on -bgsave-error yes
# ÔÚ½øÐоµÏñ±¸·Ýʱ,ÊÇ·ñ½øÐÐѹËõ¡£yes£ºÑ¹Ëõ£¬µ«ÊÇÐèҪһЩcpuµÄÏûºÄ¡£no£º²»Ñ¹Ëõ£¬ÐèÒª¸ü¶àµÄ´ÅÅ̿ռ䡣
rdbcompression yes
# Ò»¸öCRC64µÄУÑé¾Í±»·ÅÔÚÁËÎļþĩ⣬µ±´æ´¢»òÕß¼ÓÔØrbdÎļþµÄʱºò»áÓÐÒ»¸ö10%×óÓÒµÄÐÔÄÜϽµ£¬ÎªÁË´ïµ½ÐÔÄܵÄ×î´ó»¯£¬Äã¿ÉÒԹصôÕâ¸öÅäÖÃÏî¡£
rdbchecksum yes
# ¿ìÕÕµÄÎļþÃû
dbfilename dump.rdb
# ´æ·Å¿ìÕÕµÄĿ¼
dir ./ |
£¨2£©´´½¨¿ìÕյķ½·¨
a. ¿Í»§¶Ë¿ÉÒÔͨ¹ýÏëredis·¢ËÍbesaveÃüÁîÀ´´´½¨Ò»¸ö¿ìÕÕ£¬¶ÔÓÚÖ§³ÖbgsaveÃüÁîµÄƽ̨À´Ëµ£¨»ù±¾ÉÏËùÓÐÆ½Ì¨¶¼Ö§³Ö£¬³ýÁËwindowsƽ̨£©£¬redis»áµ÷ÓÃforkÀ´´´½¨Ò»¸ö×Ó½ø³Ì£¬È»ºó×Ó½ø³Ì¸ºÔ𽫿ìÕÕдÈë´ÅÅÌ£¬¶ø¸¸½ø³Ì¼ÌÐø´¦ÀíÃüÁîÇëÇó
b. ¿Í»§¶Ë»¹¿ÉÒÔÏòredis·¢ËÍsaveÃüÁîÀ´´´½¨Ò»¸ö¿ìÕÕ£¬½Óµ½saveÃüÁîµÄredis·þÎñÆ÷ÔÚ¿ìÕÕ´´½¨Íê±Ï֮ǰ²»ÔÙÏìÓ¦ÈÎºÎÆäËûÃüÁsaveÃüÁî²»³£Óã¬ÎÒÃÇͨ³£Ö»»áÔÚûÓÐ×ã¹»ÄÚ´æÈ¥Ö§³ÖbgsaveµÄÇé¿öÏ£¬ÓÖ»òÕß¼´Ê¹µÈ´ý³Ö¾Ã»¯²Ù×÷Ö´ÐÐÍê±ÏÒ²ÎÞËùνµÄÇé¿öÏ£¬²Å»áʹÓÃÕâ¸öÃüÁî
c. µ±redisͨ¹ýshutdownÃüÁî½ÓÊÕµ½¹Ø±Õ·þÎñÆ÷ÇëÇóʱ£¬»òÕß½ÓÊÕµ½±ê×¼termÃüÁîʱ£¬»áÖ´ÐÐÒ»¸ösaveÃüÁ×èÈûËùÓпͻ§¶Ë£¬²»ÔÙÖ´Ðпͻ§¶Ë·¢Ë͵ÄÈκÎÃüÁ²¢ÔÚsaveÃüÁîÖ´ÐÐÍê±ÏÖ®ºó¹Ø±Õ·þÎñÆ÷
d. µ±Ò»¸öredis·þÎñÆ÷Á´½ÓÁíÒ»¸öredis·þÎñÆ÷£¬²¢Ïò¶Ô·½·¢ËÍsyncͬ²½ÃüÁîÀ´¿ªÊ¼Ò»´Î¸´ÖƲÙ×÷ʱ£¬Èç¹ûÖ÷·þÎñÆ÷ĿǰûÓÐÖ´ÐÐbgsave²Ù×÷£¬»òÕßÖ÷·þÎñÆ÷²¢·Ç¸Õ¸ÕÖ´ÐÐÍêbgsave²Ù×÷£¬ÄÇôÖ÷·þÎñÆ÷¾Í»áÖ´ÐÐbgsave
£¨3£©AOF³Ö¾Ã»¯ÅäÖÃ
# ÊÇ·ñ¿ªÆôAOF£¬Ä¬ÈϹرգ¨no£©
appendonly yes
# Ö¸¶¨ AOF ÎļþÃû
appendfilename appendonly.aof
# RedisÖ§³ÖÈýÖÖ²»Í¬µÄˢдģʽ£º
# appendfsync always #ÿ´ÎÊÕµ½Ð´ÃüÁî¾ÍÁ¢¼´Ç¿ÖÆÐ´Èë´ÅÅÌ£¬ÊÇ×îÓб£Ö¤µÄÍêÈ«µÄ³Ö¾Ã»¯£¬µ«ËÙ¶ÈÒ²ÊÇ×îÂýµÄ£¬Ò»°ã²»ÍƼöʹÓá£
appendfsync everysec #ÿÃëÖÓÇ¿ÖÆÐ´Èë´ÅÅÌÒ»´Î£¬ÔÚÐÔÄܺͳ־û¯·½Ãæ×öÁ˺ܺõÄÕÛÖУ¬ÊÇÊÜÍÆ¼öµÄ·½Ê½¡£
# appendfsync no #ÍêÈ«ÒÀÀµOSµÄдÈ룬һ°ãΪ30Ãë×óÓÒÒ»´Î£¬ÐÔÄÜ×îºÃµ«Êdz־û¯×îûÓб£Ö¤£¬²»±»ÍƼö¡£
#ÔÚÈÕÖ¾ÖØÐ´Ê±£¬²»½øÐÐÃüÁî×·¼Ó²Ù×÷£¬¶øÖ»Êǽ«Æä·ÅÔÚ»º³åÇøÀ±ÜÃâÓëÃüÁîµÄ×·¼ÓÔì³ÉDISK
IOÉϵijåÍ»¡£
#ÉèÖÃΪyes±íʾrewriteÆÚ¼ä¶ÔÐÂд²Ù×÷²»fsync,ÔÝʱ´æÔÚÄÚ´æÖÐ,µÈrewriteÍê³ÉºóÔÙдÈ룬ĬÈÏΪno£¬½¨Òéyes
no-appendfsync-on-rewrite yes
#µ±Ç°AOFÎļþ´óСÊÇÉÏ´ÎÈÕÖ¾ÖØÐ´µÃµ½AOFÎļþ´óСµÄ¶þ±¶Ê±£¬×Ô¶¯Æô¶¯ÐµÄÈÕÖ¾ÖØÐ´¹ý³Ì¡£
auto-aof-rewrite-percentage 100
#µ±Ç°AOFÎļþÆô¶¯ÐµÄÈÕÖ¾ÖØÐ´¹ý³ÌµÄ×îСֵ£¬±ÜÃâ¸Õ¸ÕÆô¶¯ReidsʱÓÉÓÚÎļþ³ß´ç½ÏСµ¼ÖÂÆµ·±µÄÖØÐ´¡£
auto-aof-rewrite-min-size 64mb |
£¨4£©AOFÖØÐ´ÔÀí
AOF ÖØÐ´ºÍ RDB ´´½¨¿ìÕÕÒ»Ñù£¬¶¼ÇÉÃîµØÀûÓÃÁËдʱ¸´ÖÆ»úÖÆ:
a. Redis Ö´ÐÐ fork() £¬ÏÖÔÚͬʱӵÓи¸½ø³ÌºÍ×Ó½ø³Ì
b. ×Ó½ø³Ì¿ªÊ¼½«Ð AOF ÎļþµÄÄÚÈÝдÈëµ½ÁÙʱÎļþ
c . ¶ÔÓÚËùÓÐÐÂÖ´ÐеÄдÈëÃüÁ¸¸½ø³ÌÒ»±ß½«ËüÃÇÀÛ»ýµ½Ò»¸öÄڴ滺´æÖУ¬Ò»±ß½«ÕâЩ¸Ä¶¯×·¼Óµ½ÏÖÓÐ
AOF ÎļþµÄĩ⣬ÕâÑùÑù¼´Ê¹ÔÚÖØÐ´µÄÖÐ;·¢ÉúÍ£»ú£¬ÏÖÓÐµÄ AOF ÎļþÒ²»¹Êǰ²È«µÄ
d. µ±×Ó½ø³ÌÍê³ÉÖØÐ´¹¤×÷ʱ£¬Ëü¸ø¸¸½ø³Ì·¢ËÍÒ»¸öÐźţ¬¸¸½ø³ÌÔÚ½ÓÊÕµ½ÐźÅÖ®ºó£¬½«Äڴ滺´æÖеÄËùÓÐÊý¾Ý×·¼Óµ½ÐÂ
AOF ÎļþµÄĩβ
×¢Ò⣺ÔÚ½«Äڴ滺´æÖеÄÊý¾Ý×·¼Óµ½ÐÂAOFÎļþĩβºÍrenameʱ£¬Ö÷½ø³ÌÊÇ×èÈûµÄ
|