前言:
Redis 是完全開源免費的,遵守BSD協議,是一個高性能的key-value數據庫。
Redis 與其他 key - value 緩存產品有以下三個特點:
- Redis支持數據的持久化,可以將內存中的數據保存在磁盤中,重啓的時候可以再次加載進行使用。
- Redis不僅僅支持簡單的key-value類型的數據,同時還提供list,set,zset,hash等數據結構的存儲。
- Redis支持數據的備份,即master-slave模式的數據備份。
一、數據庫兩大類型介紹
- 數據庫分爲關係型數據庫(SQL)和非關係型數據庫(NoSQL)
1.1 關係型數據庫(SQL)
-
關係型數據庫:是指採用了關係模型賴組織數據的數據庫,以其行和列的形式存儲數據,以便用戶理解,關係型數據庫這一系列的行和列被稱爲表,多組表組成了庫。一般面向於記錄
-
屬於關係型數據的有:Oracle、Mysql、SQL Server、Microsoft Access、DB2等等。
-
優點:
① 易於維護:都是使用表結構,格式一致
② 使用方便:SQL語言通用,可用於複雜查詢
③ 複雜操作:支持SQL,可用於一個表以及多個表之間非常複雜的查詢
-
缺點:
① 讀寫性能比較差,尤其是海量數據的高效率讀寫
② 固定的表結構,靈活度稍欠
③ 對於高併發讀寫的需求,傳統關係型數據庫節點的硬盤I/O是一個很大的瓶頸
1.2 非關係型數據庫(NoSQL)
-
非關係型數據庫:“Not Only SQL” ,“不僅僅是SQL”,這是對非關係型數據庫的總稱。
-
屬於非關係型數據庫的有:Redis、MongDb、Hbase、CouhDB、Memcache等
-
非關係型數據庫嚴格意義上不是一種數據庫,應該屬於一種數據結構化存儲方式的集合,可以是文檔類型、圖形類型、列存儲類型,鍵值對等
-
優點:
① 格式靈活:存儲數據的格式可以是以 key-value(鍵-值)的形式、文檔形式、圖片形式等等,文檔形式、圖片形式等等,使用靈活,應用場景廣泛,而關係型數據庫則只支持基礎類型
② 速度快:NoSQL可以使用硬盤或者隨機存儲器作爲載體,而關係型數據庫只能使用硬盤;
③ 高可擴展性;
④ 成本低,NoSQL數據庫部署簡單,基本都是開源軟件
-
缺點:
① 不提供SQL支持,學習和使用成本較高;
② 不支持事務,容錯率低
③ 數據結構相對複雜,複雜查詢方面稍欠
1.3 非關係型數據庫產生背景
- ① High performance----對數據庫高併發讀寫需求
- ② Huge Storage----對海量數據高效存儲與訪問需求
- ③ High Scalability && High Availability----對數據高可擴展性與高可用性需求
二、Redis簡介
2.1 Redis概述
-
Redis是一個基於BSD開源的項目,是一個把結構化的數據放在內存中的一個存儲系統,你可以把它作爲數據庫,緩存和消息中間件來使用。同時支持strings,lists,hashes,sets,sorted sets,bitmaps,hyperloglogs和geospatial indexes等數據類型。它還內建了複製,lua腳本,LRU,事務等功能,通過redis sentinel實現高可用,通過redis cluster實現了自動分片。以及事務,發佈/訂閱,自動故障轉移等等。
-
簡單的說:
redis是一個完全開源免費的key-value內存數據庫
通常被認爲是一個數據結構服務器,主要是因爲其有着豐富的數據結構 strings、map、 list、sets、 sorted sets
2.2 Redis優缺點
-
Redis 優點
具有極高的數據讀寫速度
支持豐富的數據類型
支持數據的持久化
原子性
支持數據備份
-
Redis 缺點
數據容量收到物理內存的限制,不能用於海量數據的高性能讀寫,因此Redis適合的場景主要侷限在較小數據量的高性能操作和運算上
2.3 Redis 和Memcache比較
-
① 存儲方式
memecache 把數據全部存在內存之中,斷電後會掛掉,數據不能超過內存大小
redis有部份存在硬盤上,這樣能保證數據的持久性,支持數據的持久化(筆者注:有快照和AOF日誌兩種持久化方式,在實際應用的時候,要特別注意配置文件快照參數,要不就很有可能服務器頻繁滿載做dump)。
-
② 數據支持類型
redis在數據支持上要比memecache多的多
-
③ 使用底層模型不同
新版本的redis直接自己構建了VM 機制 ,因爲一般的系統調用系統函數的話,會浪費一定的時間去移動和請求
-
④ 運行環境不同
redis目前官方只支持LINUX 上去行,從而省去了對於其它系統的支持,這樣的話可以更好的把精力用於本系統 環境上的優化,雖然後來微軟有一個小組爲其寫了補丁。但是沒有放到主幹上
-
⑤ value大小
redis最大可以達到1G
memcache只有1M
-
redis 相比memcached 的優勢
- memcached所有的值均是簡單的字符串,redis作爲其替代者,支持更爲豐富的數據類型;
- redis的速度比memcached快很多;
- redis可以持久化其數據;
- Memcache 支持結構化,但是 Redis支持結構化和非結構化。
三、redis安裝、部署
3.1 實驗環境
- 使用centos系統
- 下載redis-5.0.7軟件包,地址:https://redis.io/
3.2 實驗過程
3.2.1 redis 安裝
- ① 安裝編譯工具
[root@localhost ~]# yum install gcc gcc-c++ make -y
- ② 下載共享文件中的redis軟件包、解壓
[root@localhost ~]# mount.cifs //192.168.226.1/LAMP-C7 /mnt
Password for root@//192.168.226.1/LAMP-C7:
[root@localhost ~]# cd /mnt/redis
[root@localhost redis]# tar xzvf redis-5.0.7.tar.gz -C /opt
......省略部分內容
-
③ make && make install
因爲解壓的軟件中的配置腳本已經被封裝化了,所以直接make即可
[root@localhost redis]# cd /opt/redis-5.0.7/
[root@localhost redis-5.0.7]# ls
00-RELEASENOTES deps README.md runtest-moduleapi tests
BUGS INSTALL redis.conf runtest-sentinel utils
CONTRIBUTING Makefile runtest sentinel.conf
COPYING MANIFESTO runtest-cluster src
[root@localhost redis-5.0.7]# make
......省略部分內容
#make install 需要指定安裝路徑(命令文件存放位置)
[root@localhost redis-5.0.7]# make PREFIX=/usr/local/redis/ install
......省略部分內容
- ④ 創建軟鏈接,便於系統管理
[root@localhost redis-5.0.7]# ln -s /usr/local/redis/bin/* /usr/local/bin/
- ⑤ 執行安裝腳本,查看端口號
[root@localhost ~]# /opt/redis-5.0.7/utils/install_server.sh
-
只有擴展服務目錄位置需要手動修改,其他全部執行回車即可。如下:
-
可查看配置文件
[root@localhost redis]# cd /etc/redis/
[root@localhost redis]# ls
6379.conf
- 查看端口
[root@localhost redis]# netstat -natp | grep 6379
tcp 0 0 127.0.0.1:6379 0.0.0.0:* LISTEN 7221/redis-server 1
- ⑥ 我們可以使用redis_6379來控制服務狀態
[root@localhost redis]# /etc/init.d/redis_6379 stop
Stopping ...
Redis stopped
[root@localhost redis]# netstat -natp | grep 6379
tcp 0 0 127.0.0.1:6379 127.0.0.1:39690 TIME_WAIT -
[root@localhost redis]# netstat -natp | grep 6379
tcp 0 0 127.0.0.1:6379 127.0.0.1:39690 TIME_WAIT -
[root@localhost redis]# /etc/init.d/redis_6379 start
Starting Redis server...
[root@localhost redis]# netstat -natp | grep 6379
tcp 0 0 127.0.0.1:6379 0.0.0.0:* LISTEN 7478/redis-server 1
tcp 0 0 127.0.0.1:6379 127.0.0.1:39690 TIME_WAIT -
[root@localhost redis]# netstat -natp | grep 6379
tcp 0 0 127.0.0.1:6379 0.0.0.0:* LISTEN 7478/redis-server 1
tcp 0 0 127.0.0.1:6379 127.0.0.1:39690 TIME_WAIT -
[root@localhost redis]#
- ⑦ 修改配置文件,添加主機IP地址
[root@localhost redis]# vim /etc/redis/6379.conf
#70行,在監聽地址的IP中添加本地IP 192.168.226.128
bind 127.0.0.1 192.168.226.128
----》wq
- ⑧ 使用遠程連接測試
[root@localhost redis]# /etc/init.d/redis_6379 restart
Stopping ...
Redis stopped
Starting Redis server...
[root@localhost redis]# redis-cli -h 192.168.226.128 -p 6379
192.168.226.128:6379>
#需要在配置文件中添加監聽地址,否則會顯示無法連接
3.3 Redis 常用命令
3.3.1 查詢命令
#查看主列表的幫助信息
192.168.226.128:6379> help @list
BLPOP key [key ...] timeout
summary: Remove and get the first element in a list, or block until one is available
since: 2.0.0
BRPOP key [key ...] timeout
summary: Remove and get the last element in a list, or block until one is available
since: 2.0.0
....省略部分內容
#查看set信息
192.168.226.128:6379> help set
#以下是語法
SET key value [expiration EX seconds|PX milliseconds] [NX|XX]
summary: Set the string value of a key
since: 1.0.0
group: string
#自動提示功能:輸入“set” 之後會有提示信息
192.168.226.128:6379> set key value [expiration EX seconds|PX millisecond
#創建set、查詢keys和匹配exists
192.168.226.128:6379> set teacher zhangsan
OK
192.168.226.128:6379> set tea red
OK
192.168.226.128:6379> keys *
1) "tea"
2) "teacher"
192.168.226.128:6379> keys t??
1) "tea"
192.168.226.128:6379> get tea
"red"
192.168.226.128:6379> exists tea
(integer) 1
192.168.226.128:6379> exists teas
(integer) 0
3.3.2 存放數據命令
-
① Redis SET 命令用於設置給定 key 的值。如果 key 已經存儲其他值, SET 就覆寫舊值,且無視類型
基本語法:SET KEY_NAME VALUE
示例:
192.168.226.128:6379> set teacher zhangsan #設定鍵--值
OK #返回值
192.168.226.128:6379> get teacher #查看/獲取鍵--值
"zhangsan"
192.168.226.128:6379> set teacher changzhi #覆蓋值
OK
192.168.226.128:6379> get teacher
"changzhi"
-
返回值 :OK
在 Redis 2.6.12 以前版本, SET 命令總是返回 OK 。
從 Redis 2.6.12 版本開始, SET 在設置操作成功完成時,才返回 OK 。
-
② Redis Get 命令用於獲取指定 key 的值。如果 key 不存在,返回 nil 。如果key 儲存的值不是字符串類型,返回一個錯誤。
基本語法:GET KEY_NAME
示例:
192.168.226.128:6379> set teacher changzhi #覆蓋值
OK
192.168.226.128:6379> get teacher
"changzhi"
- ③ Redis Get 命令用於獲取指定 key 的值。
- 基本語法:GET KEY_NAME
- 返回值:返回 key 的值,如果 key 不存在時,返回 nil。 如果 key 不是字符串類型,那麼返回一個錯誤。
192.168.226.128:6379> keys * #查看當前數據庫中所有的鍵
1) "tea"
2) "teacher"
192.168.226.128:6379> keys t* #查看當前數據庫中以t開頭的鍵
1) "tea"
2) "teacher"
192.168.226.128:6379> keys v? #查看當前數據庫中以t開頭後面包含任意一個字符的鍵. 一個"?"代表任意一個字符
(empty list or set)
192.168.226.128:6379> keys t??
1) "tea"
- ④ exists:判斷鍵值是否存在
- 基本語法:EXISTS KEY_NAME
- 返回值:若 key 存在返回 1 ,否則返回 0
192.168.226.128:6379> exists tea
(integer) 1
192.168.226.128:6379> exists t
(integer) 0
- ⑤ Redis DEL 命令用於刪除已存在的鍵。不存在的 key 會被忽略。
- 基本語法:DEL KEY_NAME
- 返回值:被刪除key的數量
192.168.226.128:6379> exists tea
(integer) 1
192.168.226.128:6379> del tea #刪除tea這個鍵
(integer) 1
192.168.226.128:6379> exists tea
(integer) 0
-
⑥ Redis Type 命令用於返回 key 所儲存的值的類型。
-
基本語法:TYPE KEY_NAME
-
返回值:返回key的數據類型,數據類型包括:
none (key不存在)
string (字符串)
list (列表)
set (集合)
zset (有序集)
hash (哈希表)
192.168.226.128:6379> type teacher
string
-
⑦ rename與renamenx
-
Redis Rename 命令用於修改 key 的名稱
-
基本語法:RENAME OLD_KEY_NAME NEW_KEY_NAME
-
返回值:
改名成功時提示 OK ,失敗時候返回一個錯誤
當 OLD_KEY_NAME 和 NEW_KEY_NAME 相同,或者 OLD_KEY_NAME 不存在時,返回一個錯誤
NEW_KEY_NAME 已經存在時, RENAME 命令將覆蓋舊值。
-
-
Redis Renamenx 命令用於在新的 key 不存在時修改 key 的名稱 。
- 基本語法:RENAMENX OLD_KEY_NAME NEW_KEY_NAME
- 返回值:修改成功時,返回 1 。 如果 NEW_KEY_NAME 已經存在,返回 0
#rename示例
192.168.226.128:6379> type teacher
string
192.168.226.128:6379> set school new
OK
192.168.226.128:6379> rename school work
OK
192.168.226.128:6379> exists school
(integer) 0
192.168.226.128:6379> exists work
(integer) 1
#renamenx示例
192.168.226.128:6379> set boys trouble
OK
192.168.226.128:6379> exists girls
(integer) 0
192.168.226.128:6379> renamenx boys girls
(integer) 1
- ⑧ Redis Dbsize 命令用於返回當前數據庫的 key 的數量。
- 基本語法:DBSIZE
- 返回值:當前數據庫的 key 的數量
192.168.226.128:6379> dbsize
(integer) 3
3.3.3 Redis多數據庫操作
- Redis 支持多數據庫,默認支持16個數據庫,分別爲0-15(命名)。
- 多數據庫之間相互獨立,互不干擾
- 多數據庫常用命令如下
- ① Redis Select 命令用於切換到指定的數據庫,數據庫索引號 index 用數字值指定,以 0 作爲起始索引值。
- 基本語法:SELECT index
- 返回值:0-15返回 OK ,切換到的數據庫超過15,則返回error
192.168.226.128:6379> select 10
OK
192.168.226.128:6379[10]> select 11
OK
192.168.226.128:6379[11]> select 19
(error) ERR DB index is out of range
- ② Redis MOVE 命令用於將當前數據庫的 key 移動到給定的數據庫 db 當中。
- 基本語法:MOVE KEY_NAME DESTINATION_DATABASE
- 返回值:移動成功返回 1 ,失敗則返回 0 。
192.168.226.128:6379> keys *
1) "girls"
2) "teacher"
3) "work"
192.168.226.128:6379> move work 1 #將work鍵移動到數據庫1中
(integer) 1 #成功
192.168.226.128:6379> keys * #已移出數據庫0
1) "girls"
2) "teacher"
192.168.226.128:6379> set work money #重新設定work鍵-值
OK
192.168.226.128:6379> keys *
1) "girls"
2) "teacher"
3) "work"
192.168.226.128:6379> move work 1 #再次移動work到數據庫1
(integer) 0 #失敗,因爲數據庫1中已有同名的鍵
- ③ Redis Flushdb 命令用於清空當前數
- **據庫中的所有 key。 **
- 基礎語法:FLUSHDB
- 返回值:總是返回 OK
192.168.226.128:6379> keys *
1) "girls"
2) "teacher"
3) "work"
192.168.226.128:6379> flushdb
OK
192.168.226.128:6379> keys *
(empty list or set)
四、redis-benchmark工具
-
Redis 性能測試是通過同時執行多個命令實現的
-
基本語法:redis-benchmark [option] [option value]
-
需注意:測試命令是在redis 的目錄下執行的,而不是redis客戶端的內部指令
-
redis 性能測試工具可選參數如下所示
-
測試示例:
#該壓測會把每一項功能進行測試
[root@localhost redis]# redis-benchmark -h 192.168.226.128 -p 6379 -c 100 -n 100000
====== MSET (10 keys) ======
100000 requests completed in 1.23 seconds #10萬請求完成花費時間
100 parallel clients
3 bytes payload
keep alive: 1
70.06% <= 1 milliseconds
99.11% <= 2 milliseconds
99.20% <= 3 milliseconds
99.27% <= 4 milliseconds
99.30% <= 7 milliseconds
99.34% <= 8 milliseconds
99.93% <= 9 milliseconds
100.00% <= 9 milliseconds
81566.07 requests per second
#還可以查看最典型的set和get所花費的時間
#測試存取大小爲100字節的數據包的性能
[root@localhost redis]# redis-benchmark -h 192.168.226.128 -p 6379 -q -d 100
PING_INLINE: 98814.23 requests per second
PING_BULK: 90744.10 requests per second
SET: 91575.09 requests per second
GET: 93896.71 requests per second
INCR: 96899.23 requests per second
LPUSH: 90090.09 requests per second
RPUSH: 89445.44 requests per second
LPOP: 90991.81 requests per second
RPOP: 92421.44 requests per second
SADD: 95510.98 requests per second
HSET: 94428.70 requests per second
SPOP: 96899.23 requests per second
LPUSH (needed to benchmark LRANGE): 80645.16 requests per second
LRANGE_100 (first 100 elements): 39824.77 requests per second
LRANGE_300 (first 300 elements): 12400.79 requests per second
LRANGE_500 (first 450 elements): 8130.74 requests per second
LRANGE_600 (first 600 elements): 6084.58 requests per second
MSET (10 keys): 74738.41 requests per second
#此處可以看到處理數據包所花費的時間,我們也可以進行內存優化,之後會進行講述
五、Redis 持久化
5.1 Redis持久化概述
- Redis 是運行在內存中,內存中的數據斷電就會丟失
- Redis支持RDB和AOF兩種持久化機制,持久化功能有效地避免因進程退出造成的數據丟失問題,爲了能重用 Redis 數據,或者防止系統故障,需要將 Redis 中的數據寫入到磁盤空間中,即持久化。
5.2 Redis持久化分類
- ① RDB方式:創建快照的方式獲取某一時刻Redis中所有數據的副本
- ② AOF 方式:將執行的寫命令寫道文件末尾,以日誌的方式來記錄數據的變化
5.2.1 RDB持久化
-
RDB持久化是把當前進程數據生成快照保存到硬盤的過程,觸發RDB持久化過程分爲手動觸發和自動觸發
-
觸發條件:
① 在指定的時間間隔內,執行指定次數的寫操作(在配置文件中設置)
② 執行save 或者 bgsavfe(異步)命令
- save命令:阻塞當前Redis服務器,直到RDB過程完成爲止,對於內存 比較大的實例會造成長時間阻塞,線上環境不建議使用
- bgsave命令:Redis進程執行fork操作創建子進程,RDB持久化過程由子進程負責,完成後自動結束。阻塞只發生在fork階段,一般時間很短
③ 執行flushall命令,清除數據庫所有數據
④ 執行shutdown命令,保證服務器正常關閉且部丟失任何數據
-
優缺點
- 適合大規模的數據恢復;
- 如果業務對數據完整性和一致性要求不高,RDB 是很好的選擇;
- 數據的完整性和一致性不高;
- 備份時佔用內存。
-
通過RDB 文件恢復數據
將 dump.rdb 文件拷貝到 redis 的安裝目錄的 bin 目錄下,重啓 redis 服務即可
-
配置文件項
[root@localhost redis]# vim /etc/redis/6379.conf
#219-221行
save 900 1
save 300 10
save 60 10000
#900秒內做1次寫的操作 自動進行保存
#300秒內做10次寫的操作 自動保存
#60秒內做10000次寫的操作 自動保存
#254行,數據保存的目錄命:dump.rdb
dbfilename dump.rdb
#264 目錄路徑
dir /var/lib/redis/6379
#242 壓縮功能默認也是開啓的
rdbcompression yes
5.2.2 AOF持久化
- AOF文件本之上是一個redo log(重做日誌) Redis 默認是不開啓AOF的
- 彌補 RDB 的不足(數據的不一致性);
- 採用日誌的形式來記錄每個寫操作,並追加到文件中;
- Redis 重啓會根據日誌文件的內容將寫指令從前到後執行一次以完成數據的恢復工作。
- 開啓AOF功能需要設置通過配置文件:appendonly.aof中的appendonly yes選項,具體如下:
[root@localhost redis]# vim /etc/redis/6379.conf
#700行 修改爲yes 開啓AOF持久化功能
appendonly yes
#704行,AOF同步的文件,在進行文件恢復的時候需要把這個文件放到/bin目錄
appendfilename "appendonly.aof"
#729-731行三個功能
#同步持久化,每次發生數據變化會立刻寫入磁盤
#每秒同步(默認項),每秒異步記錄一次
#不同步,交給操作系統決定任何同步
appendfsync always
#appendfsync everysec
# appendfsync no
#796行 忽略最後一條語句(因爲可能存在文件)
aof-load-truncated yes
-
AOF的重寫機制
- AOF的工作原理是將寫的操作追加到文件中,這會導致文件中的冗餘會越來越多
- 當AOF文件的大小超過所設定的閾值時,Redis就會對AOF文件的內容壓縮
-
AOF的重寫原理
- Redis 會fork 出一條新進程,讀取內存中的數據(並沒有讀取舊文件),並重寫到一個臨時文件中,最後替換舊的aof文件
-
AOF的重寫配置
Bgrewriteaof命令:異步執行一個 AOF(AppendOnly File) 文件重寫操作
即使 Bgrewriteaof 執行失敗,也不會有任何數據丟失,因爲舊的 AOF 文件在 Bgrewriteaof 成功之前不會被修改
**注意:**從 Redis 2.4 開始, AOF 重寫由 Redis 自行觸發, BGREWRITEAOF 僅僅用於手動觸發重寫操作。
[root@localhost redis]# vim /etc/redis/6379.conf
#752行 去重功能,可以開啓,但是需要設定閾值條件來限制觸發去重操作
no-appendfsync-on-rewrite yes
#771-772行。
#大小超過64M.同步內容超過上次日誌重寫時aof文件2倍大小時,會觸發去重操作,刪除多出的冗餘內容
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
六、Redis 性能管理
6.1 內存碎片率
-
① 操作系統分配的內存值 used_memory_rss 除以 redis 使用的內存值 used_memory 計算得出的;
-
② 內存碎片是由操作系統低效的分配/回收物理內存導致的
- 不連續的物理內存分配
-
③ 跟蹤內存碎片率對理解 redis 實例的資源性能是非常重要的;
內存碎片率稍大於 1 是合理的,這個值表示內存碎片率比較低;
內存碎片率超過 1.5 ,說明 redis 消耗了實際需要物理內存的 150% ,其中 50% 是內存碎片率;
內存碎片率低於 1 的,說明 Redis 內存分配超出了物理內存,操作系統正在進行內存交換。
[root@localhost redis]# redis-cli -h 192.168.226.128 -p 6379
192.168.226.128:6379> info memory
# Memory
used_memory:853336 #內存使用總量
used_memory_human:833.34K #內存使用總量
used_memory_rss:3481600
used_memory_rss_human:3.32M
used_memory_peak:853336
used_memory_peak_human:833.34K
used_memory_peak_perc:100.01%
used_memory_overhead:841110
used_memory_startup:791416
................省略部分內容
mem_fragmentation_ratio:4.29 #內存碎片率
mem_fragmentation_bytes:2669288
mem_not_counted_for_evict:0
mem_replication_backlog:0
mem_clients_slaves:0
mem_clients_normal:49694
mem_aof_buffer:0
mem_allocator:jemalloc-5.1.0
active_defrag_running:0
lazyfree_pending_objects:0
6.2 內存使用率
- Redis 實例的內存使用率超過可用最大內存,操作系統開始進行內存與 swqp 空間交換;
- 避免內存交換
- 針對緩存數據大小選擇;
- 儘可能的使用 Hash 數據結構;
- 設置 key 的過期時間
6.3 回收 Key
- 保證合理分配Redis有限的內存資源
- 當內存使用達到設置的最大閾值時,需要選擇一種key回收策略
- 默認情況下回收策略時禁止刪除的;
- redis.conf 配置文件中修改maxmemory-policy屬性值
用達到設置的最大閾值時,需要選擇一種key回收策略
- 默認情況下回收策略時禁止刪除的;
- redis.conf 配置文件中修改maxmemory-policy屬性值
總結
本篇博客僅簡單介紹了redis的配置、功能、之後會慢慢更新其他實用功能