❶ redis 資料庫中查看有哪些數據
使用info查看Keyspace
代表有多少個庫或鍵名空間,然後select 相應的id選擇庫,
scan 0查詢所有的鍵。
❷ 查詢數據放入了redis中緩存,怎麼查看緩存的數據
普通分頁
一般分頁做緩存都是直接查找出來,按頁放到緩存里,但是這種緩存方式有很多缺點。
如緩存不能及時更新,一旦數據有變化,所有的之前的分頁緩存都失效了。
比如像微博這樣的場景,微博下面現在有一個頂次數的排序。這個用傳統的分頁方式很難應對。
一種思路
最近想到了另一種思路。
數據以ID為key緩存到Redis里;
把數據ID和排序打分存到Redis的skip list,即zset里;
當查找數據時,先從Redis里的skip list取出對應的分頁數據,得到ID列表。
用multi get從redis上一次性把ID列表裡的所有數據都取出來。如果有缺少某些ID的數據,再從資料庫里查找,再一塊返回給用戶,並把查出來的數據按ID緩存到Redis里。
在最後一步,可以有一些小技巧:
比如在缺少一些ID數據的情況下,先直接返回給用戶,然後前端再用ajax請求缺少的ID的數據,再動態刷新。
❸ 怎麼判斷redis中有沒有數據
redis-cli 中。 使用 info Keyspace 查看存儲數據的相關信息。 通過 keys * 查看所有的 key
❹ 如何在linux中查詢redis的數據
1、執行如圖是命令,查看redis服務是否啟動。
❺ 如何查詢redis存儲的所有數據
1、打開reidis,選擇第三個資料庫。
❻ 如何通過命令查看redis數據
如何查看redis最近使用的命令使用redis的腳本功能實現redis中數據簡單查詢,有需要的朋友可以參考下。在redis的設計中,key是一切,對於redis是可見的,而value對於redis來說就是一個位元組數組,redis並不知道你的value中存儲的是什麼,所以要
❼ 查看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中的數據
使用Redis的腳本功能實現Redis中數據簡單查詢,有需要的朋友可以參考下。 在Redis的設計中,key是一切,對於Redis是可見的,而value對於Redis來說就是一個位元組數組,Redis並不知道你的value中存儲的是什麼
❾ Redis有哪些數據類型
一、String | 字元串類型
Redis的字元串類型,可以存儲字元串、整數或浮點數,如果存儲的是整數或者浮點數,還能執行自增或自減操作。Reids的string類型是二進制的,可以包含任何數據,比如一個序列化的對象、一個圖片、位元組流等,不過存儲大小上限是512M。
Redis底層定義了自己的一種數據結構。
二、List | 列表類型
Redis的列表類型和許多編程語言中的列表類型類似,可以有序地存儲多個字元串,支持從列表的左端和右端推入或彈出元素,Redis列表的底層實現是壓縮列表,Redis內容自己實現的數據結構和雙端鏈表。
將一個或者多個value值插入列表的表頭。如果 key 不存在,會創建一個空列表並執行 LPUSH 操作。當 key
存在但不是列表類型時,返回一個錯誤。
三、set | 集合類型
Redis的集合以無序的方式存儲多個不同的元素,這里要注意的是無序和不同。除了對集合能快速執行添加、刪除、檢查一個元素是否在集合中之外,還可以對多個集合執行交集、並集和差集運算。
Redis的集合類型底層實現主要是通過一種叫做字典的數據結構。不過Redis為了追求極致的性能,會根據存儲的值是否是整數,選擇一種intset的數據結構。當滿足一定條件後,會切換成字典的實現。
四、hash | 散列表(哈希表)
Redis的hash類型其實就是一個縮減版的redis。它存儲的是鍵值對,將多個鍵值對存儲到一個redis鍵裡面。
hash類型的底層主要也是基於字典這種數據結構來實現的。
五、zset | 有序集合
有序集合相比較於集合,多個有序兩個字,我們知道set集合類型存儲的元素是無序的,那Redis有序集合是怎麼保證有序的?使用分值,有序集合里存儲這成員與分值之間的映射,並提供了分值處理命令,以及根據分值的大小有序地獲取成員或分值的命令。
Redis有序集合的實現使用了一種叫跳躍表的數據結構(簡稱跳錶,可自行查閱),同時也使用到了前面提到的壓縮列表。也是滿足一定條件的話,會自行轉換。
❿ 怎麼樣使用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;