Ⅰ 如何查詢redis的緩存文件路徑
1、首先找到redis的安裝目錄,如下圖測試環境目錄,進入到/opt/install/redis-2.8.19/src,如下圖所示。
Ⅱ 如何在linux中查詢redis的數據
1、執行如圖是命令,查看redis服務是否啟動。
Ⅲ Redis 有沒有什麼命令可以查詢當前庫有多少個 key
info可以看到所有庫的key數量
dbsize則是當前庫key的數量
上面2個都不夠精確
keys 能看的比較精確,但是如果庫里數據非常大的話,用keys會導致資料庫卡死,影響業務
Ⅳ 怎麼樣使用Redis來存儲和查詢ip數據
今天朋友打了個電話,他們網站的業務要根據客戶的ip地址快速定位客戶的地理位置。網上已經有一大堆類似的ip地址庫可以用,但問題是這些地址庫的數據表結構大多如下所示
+--------------+------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------+------------------+------+-----+---------+----------------+
| ip_id | int(11) unsigned | NO | PRI | NULL | auto_increment |
| ip_country | varchar(50) | NO | | NULL | |
| ip_startip | bigint(11) | NO | MUL | NULL | |
| ip_endip | bigint(11) | NO | MUL | NULL | |
| country_code | varchar(2) | NO | | NULL | |
| zone_id | int(11) | NO | | 0 | |
+--------------+------------------+------+-----+---------+----------------+
最核心的部分是三個: ip_startip , ip_endip 以及 ip_id 。其中 ip_id 是要查詢的結果,當然也可以把 zone_id 和 ip_country 包括進去。這里就用 ip_id 來特指查詢結果了。
面對這個表,沒什麼其它辦法,查詢語句只能是
SELECT * FROM who_ip WHERE ip_startip <= {ip} AND ip_endip >= {ip}
其中 {ip} 是要查詢的ip地址,為了方便查詢,在php中一般要用 ip2long函數把它轉換為一個整數。現在問題來了,這個表有400萬條數據,無論你怎麼優化它的索引結構(實際上我覺得這沒啥用),在以上查詢語句中都要耗費2秒以上的時間,對於一個高頻使用的介面,這顯然是不可忍受的。
REDIS能不能解決這個問題。實際上這也是朋友最關心的問題,因為知道Redis有強大數據結構和超快的速度,那麼能不能設計出適應這種查詢場景的結構。
范圍查詢,首先想到的就是Redis裡面的 Sorted Sets 結構,這也是redis中唯一可以指定范圍( SCORE 值)查詢的結構了,所以基本上希望都寄託在它身上了。
最簡單粗暴的方法就是把 ip_startip 和 ip_endip 都轉化為 Sorted Sets 里的 Score ,然後把 ip_id 定義為 Member 。這樣我們的查詢就很簡單了,只需要用 ZRANGESCORE 查詢出離ip最近SCORE對應的兩個 ip_id 即可。然後再分析,如果這兩個 ip_id 是相同的,那麼說明這個ip在這個地址段,如果不同的話證明這個ip地址沒有被任何地址段所定義,是一個未知的ip。
基本邏輯是沒有問題的,但是最大的問題還是性能上的挑戰。根據我的經驗,一個SET 裡面放10萬條數據以上就已經很慢了,如果放到400萬這種量級,我非常懷疑它跟mysql相比還有優勢嗎?
我設計的存儲結構
我的解決方案是把這個地址庫切分,每一片區最多保存65536個地址。也就是說如果一個ip地址段為 188.88.77.22 - 188.90.78.10 ,那麼我們就把它切分為
188.88.77.22 - 188.88.77.255
188.89.0.0 - 188.89.255.255
188.90.0.0 - 189.90.78.10
也就是我們保證每一個ip地址段都被保存在 xxx.xxx.0.0 - xxx.xxx.255.255的一個區段中,這個區段的理論極限是保存65536個值,實際上要遠小於這個數字。而這樣的區段理論上也有65536個,這都是ip地址的設計所限,當然實際上也遠小於這個值。
因此這樣的設計基本上就能滿足我們的性能需要了。以下是我用php寫的數據切分程序
<?php
// redis 參數
define('REDIS_HOST', '127.0.0.1');
define('REDIS_PORT', 6379);
define('REDIS_DB', 10);
define('MYSQL_HOST', 'localhost');
define('MYSQL_PORT', 3306);
define('MYSQL_USER', 'root');
define('MYSQL_PASS', '123456');
define('MYSQL_DB', 'who_brand');
define('MYSQL_TABLE', 'who_ip');
define('MYSQL_COLUMN_START', 'ip_startip');
define('MYSQL_COLUMN_END', 'ip_endip');
define('MYSQL_COLUMN_ID', 'ip_id');
define('MYSQL_PAGESIZE', 1000);
mysql_connect(MYSQL_HOST . ':' . MYSQL_PORT, MYSQL_USER, MYSQL_PASS);
mysql_select_db(MYSQL_DB);
function add_ip($page, $offset, $value) {
static $redis;
if (!$redis) {
$redis = new Redis();
$redis->connect(REDIS_HOST, REDIS_PORT);
$redis->select(REDIS_DB);
}
$key = 'ip:' . $page;
$redis->zAdd($key, $offset, $value);
}
$page = 0;
do {
$offset = $page * MYSQL_PAGESIZE;
$count = 0;
$res = mysql_query('SELECT * FROM ' . MYSQL_TABLE . ' LIMIT ' . MYSQL_PAGESIZE . " OFFSET {$offset}");
while ($ip = mysql_fetch_assoc($res)) {
$start = $ip[MYSQL_COLUMN_START];
$end = $ip[MYSQL_COLUMN_END];
$value = $ip[MYSQL_COLUMN_ID];
$startOffset = $start % 65536;
$endOffset = $end % 65536;
$start -= $startOffset;
$end -= $endOffset;
$startPage = $start / 65536;
$endPage = $end / 65536;
for ($i = $startPage; $i <= $endPage; $i ++) {
if ($i == $startPage) {
add_ip($i, $startOffset, 's:' . $value);
if ($i != $endPage) {
add_ip($i, 65535, 'e:' . $value);
}
}
if ($i == $endPage) {
add_ip($i, $endOffset, 'e:' . $value);
if ($i != $startPage) {
add_ip($i, 0, 's:' . $value);
}
}
if ($i != $endPage && $i != $startPage) {
add_ip($i, 0, 's:' . $value);
add_ip($i, 65535, 'e:' . $value);
}
}
echo ($page * MYSQL_PAGESIZE + $count) . "\n";
$count ++;
}
$page ++;
} while ($count = MYSQL_PAGESIZE);
<?php
define('REDIS_HOST', '127.0.0.1');
define('REDIS_PORT', 6379);
define('REDIS_DB', 10);
$redis = new Redis();
$redis->connect(REDIS_HOST, REDIS_PORT);
$redis->select(REDIS_DB);
$ip = ip2long('173.255.218.70');
$offset = $ip % 65536;
$page = ($ip - $offset) / 65536;
// 取出小於等於它的最接近值
$start = $redis->zRevRangeByScore('ip:' . $page, 0, $offset, array(
'limit' => array(0, 1)
));
// 取出大於等於它的最接近值
$end = $redis->zRangeByScore('ip:' . $page, $offset, 65535, array(
'limit' => array(0, 1)
));
if (empty($start) || empty($end)) {
echo 'unknown';
exit;
}
$start = $start[0];
$end = $end[0];
list ($startOp, $startId) = explode(':', $start);
list ($endOp, $endId) = explode(':', $end);
if ($startId != $endId) {
echo 'unknown';
exit;
}
echo $startId;
Ⅳ redis中怎麼查看資料庫的個數
命令:config get databases
默認16個
Ⅵ 查看redis 中有多少條數據
使用Redis的腳本功能實現Redis中數據簡單查詢,有需要的朋友可以參考下。
在Redis的設計中,key是一切,對於Redis是可見的,而value對於Redis來說就是一個位元組數組,Redis並不知道你的value中存儲的是什麼,所以要想實現比如
『select * from users where user.location="shanghai"』
這樣的查詢,在Redis是沒辦法通過value進行比較得出結果的。但是可以通過不同的數據結構類型來做到這一點。比如如下的數據定義
users:1 {name:Jack,age:28,location:shanghai} users:2 {name:Frank,age:30,location:beijing} users:location:shanghai [1]
其中users:1 users:2 分別定義了兩個用戶信息,通過Redis中的hash數據結構,而users:location:shanghai 記錄了所有上海的用戶id,通過集合數據結構實現。這樣通過兩次簡單的Redis命令調用就可以實現我們上面的查詢。
Jedis jedis = jedisPool.getResource(); Set<String> shanghaiIDs = jedis.smembers("users:location:shanghai"); //遍歷該set //... //通過hgetall獲取對應的user信息 jedis.hgetAll("users:" + shanghaiIDs[0]);
通過諸如以上的設計,可以實現簡單的條件查詢。但是這樣的問題也很多,首先需要多維護一個ID索引的集合,其次對於一些復雜查詢無能為力(當然也不能期望Redis實現像關系資料庫那樣的查詢,Redis不是干這的)。
但是Redis2.6集成了Lua腳本,可以通過eval命令,直接在RedisServer環境中執行Lua腳本,並且可以在Lua腳本中調用Redis命令。其實,就是說可以讓你用Lua這種腳本語言,對Redis中存儲的key value進行操作,這個意義就大了,甚至可以將你們系統所需的各種業務寫成一個個lua腳本,提前載入進入Redis,然後對於請求的響應,只需要調用一個個lua腳本就行。當然這樣說有點誇張,但是意思就是這樣的。
比如,現在我們要實現一個『所有age大於28歲的user』這樣一個查詢,那麼通過以下的Lua腳本就可以實現
public static final String SCRIPT = "local resultKeys={};" + "for k,v in ipairs(KEYS) do " + " local tmp = redis.call('hget', v, 'age');" + " if tmp > ARGV[1] then " + " table.insert(resultKeys,v);" + " end;" + "end;" + "return resultKeys;";
執行腳本代碼 Jedis jedis = jedisPool.getResource(); jedis.auth(auth); List<String> keys = Arrays.asList(allUserKeys); List<String> args = new ArrayList<>(); args.add("28"); List<String> resultKeys = (List<String>)jedis.evalsha(funcKey, keys, args); return resultKeys;
注意,以上的代碼中使用的是evalsha命令,該命令參數的不是直接Lua腳本字元串,而是提前已經載入到Redis中的函數的一個SHA索引,通過以下的代碼將系統中所有需要執行的函數提前載入到Redis中,我們的系統維護一個函數哈希表,後續需要實現什麼功能,就從函數表中獲取對應功能的SHA索引,通過evalsha調用就行。
String shaFuncKey = jedis.scriptLoad(SCRIPT);//載入腳本,獲取sha索引 funcTable.put(funcName_age, shaFuncKey);//添加到函數表中
通過以上的方法,便可以使較為復雜的查詢放到Redis中去執行,提高效率。
Ⅶ redis的五種數據類型是什麼
如下:
一、string
string 是 redis 最基本的類型,你可以理解成與 Memcached 一模一樣的類型,一個 key 對應一個 value。
string 類型是二進制安全的。意思是 redis 的 string 可以包含任何數據。比如jpg圖片或者序列化的對象。
string 類型是 Redis 最基本的數據類型,string 類型的值最大能存儲 512MB。
命令: SET 和 GET 命令。
二、hash
Redis hash 是一個鍵值(key=>value)對集合。
Redis hash 是一個 string 類型的 field 和 value 的映射表,hash 特別適合用於存儲對象。
HMSET, HGET 命令,HMSET 設置了兩個 field=>value 對, HGET 獲取對應 field 對應的 value。
三、list
列表是簡單的字元串列表,按照插入順序排序。可以添加一個元素到列表的頭部(左邊)或者尾部(右邊)。
列表最多可存儲 232 - 1 元素 (4294967295,每個列表可存儲40多億)。
lpush 設置值,lrange取值。
四、set
redis的set是string的無序集合。集合通過哈希表實現。
添加一個string元素到key對應的set集合中,用 sadd命令。返回1表示成功,0表示在集合中已存在,返回錯誤表示key對應的set不存在。
查看用smembers 命令。
集合內元素的唯一性,第二次插入的元素將被忽略。
集合中最大的成員數為 232 - 1(4294967295, 每個集合可存儲40多億個成員)。
五、zset
redis的zset 和 set 一樣也是string類型元素的集合,且不允許重復的成員。
不同的是每個元素都會關聯一個double類型的分數。redis正是通過分數來為集合中的成員進行從小到大的排序。zset的成員是唯一的,但分數(score)卻可以重復。
添加元素到集合,元素在集合中存在則更新對應score:zadd key score member。
Redis數據模型:
Redis的外圍由一個鍵、值映射的字典構成。與其他非關系型資料庫主要不同在於:Redis中值的類型不僅限於字元串,還支持如下抽象數據類型:
1、字元串列表。
2、無序不重復的字元串集合。
3、有序不重復的字元串集合。
4、鍵、值都為字元串的哈希表。
值的類型決定了值本身支持的操作。Redis支持不同無序、有序的列表,無序、有序的集合間的交集、並集等高級伺服器端原子操作。
Ⅷ 如何連接redis資料庫
1、在配置文件redis.conf中把綁定的Ip注釋掉
到此就連接成功了。
Ⅸ 如何通過命令查看redis數據
如何查看redis最近使用的命令使用redis的腳本功能實現redis中數據簡單查詢,有需要的朋友可以參考下。在redis的設計中,key是一切,對於redis是可見的,而value對於redis來說就是一個位元組數組,redis並不知道你的value中存儲的是什麼,所以要