国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - java實現cassandra高級操作之分頁實例(有項目具體需求)

java實現cassandra高級操作之分頁實例(有項目具體需求)

2020-09-04 15:25youzhibing2904 Java教程

這篇文章主要介紹了java實現cassandra高級操作之分頁實例(有項目具體需求),具有一定的參考價值,感興趣的小伙伴們可以參考一下。

上篇博客講到了cassandra分頁,相信大家會有所注意:下一次的查詢依賴上一次的查詢(上一次查詢的最后一條記錄的全部主鍵),不像mysql那樣靈活,所以只能實現上一頁、下一頁這樣的功能,不能實現第多少頁那樣的功能(硬要實現的話性能就太低了)。

我們先看看驅動官方給的分頁做法

如果一個查詢得到的記錄數太大,一次性返回回來,那么效率非常低,并且很有可能造成內存溢出,使得整個應用都奔潰。所以了,驅動對結果集進行了分頁,并返回適當的某一頁的數據。

一、設置抓取大?。⊿etting the fetch size)

抓取大小指的是一次從cassandra獲取到的記錄數,換句話說,就是每一頁的記錄數;我們能夠在創建cluster實例的時候給它的fetch size指定一個默認值,如果沒有指定,那么默認是5000

java" id="highlighter_666814">
?
1
2
3
4
5
6
7
8
// At initialization:
Cluster cluster = Cluster.builder()
  .addContactPoint("127.0.0.1")
  .withQueryOptions(new QueryOptions().setFetchSize(2000))
  .build();
 
// Or at runtime:
cluster.getConfiguration().getQueryOptions().setFetchSize(2000);

另外,statement上也能設置fetch size

?
1
2
Statement statement = new SimpleStatement("your query");
statement.setFetchSize(2000);

如果statement上設置了fetch size,那么statement的fetch size將起作用,否則則是cluster上的fetch size起作用。

注意:設置了fetch size并不意味著cassandra總是返回準確的結果集(等于fetch size),它可能返回比fetch size稍微多一點或者少一點的結果集。

二、結果集迭代

fetch size限制了每一頁返回的結果集的數量,如果你迭代某一頁,驅動會在后臺自動的抓取下一頁的記錄。如下例,fetch size = 20:

java實現cassandra高級操作之分頁實例(有項目具體需求)

默認情況下,后臺自動抓取發生在最后一刻,也就是當某一頁的記錄被迭代完的時候。如果需要更好的控制,ResultSet接口提供了以下方法:

getAvailableWithoutFetching() and isFullyFetched() to check the current state;

fetchMoreResults() to force a page fetch;

以下是如何使用這些方法提前預取下一頁,以避免在某一頁迭代完后才抓取下一頁造成的性能下降:

?
1
2
3
4
5
6
7
ResultSet rs = session.execute("your query");
for (Row row : rs) {
  if (rs.getAvailableWithoutFetching() == 100 && !rs.isFullyFetched())
    rs.fetchMoreResults(); // this is asynchronous
  // Process the row ...
  System.out.println(row);
}

三、保存并重新使用分頁狀態

有時候,將分頁狀態保存起來,對以后的恢復是非常有用的,想象一下:有一個無狀態Web服務,顯示結果列表,并顯示下一頁的鏈接,當用戶點擊這個鏈接的時候,我們需要執行與之前完全相同的查詢,除了迭代應該從上一頁停止的位置開始;相當于記住了上一頁迭代到了哪了,那么下一頁從這里開始即可。

為此,驅動程序會暴露一個PagingState對象,該對象表示下一頁被提取時我們在結果集中的位置。

?
1
2
3
4
5
6
7
ResultSet resultSet = session.execute("your query");
// iterate the result set...
PagingState pagingState = resultSet.getExecutionInfo().getPagingState();
 
// PagingState對象可以被序列化成字符串或字節數組
String string = pagingState.toString();
byte[] bytes = pagingState.toBytes();

PagingState對象被序列化后的內容可以持久化存儲起來,也可用作分頁請求的參數,以備后續再次被利用,反序列化成對象即可:

?
1
2
PagingState.fromBytes(byte[] bytes);
PagingState.fromString(String str);

請注意,分頁狀態只能使用完全相同的語句重復使用(相同的查詢,相同的參數)。而且,它是一個不透明的值,只是用來存儲一個可以被重新使用的狀態值,如果嘗試修改其內容或將其使用在不同的語句上,驅動程序會拋出錯誤。

具體我們來看下代碼,下例是模擬頁面分頁的請求,實現遍歷teacher表中的全部記錄:

接口:

?
1
2
3
4
5
6
7
8
9
import java.util.Map;
 
import com.datastax.driver.core.PagingState;
 
public interface ICassandraPage
{
  Map<String, Object> page(PagingState pagingState);
 
}

主體代碼:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
 
import com.datastax.driver.core.PagingState;
import com.datastax.driver.core.ResultSet;
import com.datastax.driver.core.Row;
import com.datastax.driver.core.Session;
import com.datastax.driver.core.SimpleStatement;
import com.datastax.driver.core.Statement;
import com.huawei.cassandra.dao.ICassandraPage;
import com.huawei.cassandra.factory.SessionRepository;
import com.huawei.cassandra.model.Teacher;
 
public class CassandraPageDao implements ICassandraPage
{
  private static final Session session = SessionRepository.getSession();
  
  private static final String CQL_TEACHER_PAGE = "select * from mycas.teacher;";
  
  @Override
  public Map<String, Object> page(PagingState pagingState)
  {
    final int RESULTS_PER_PAGE = 2;
    Map<String, Object> result = new HashMap<String, Object>(2);
    List<Teacher> teachers = new ArrayList<Teacher>(RESULTS_PER_PAGE);
 
    Statement st = new SimpleStatement(CQL_TEACHER_PAGE);
    st.setFetchSize(RESULTS_PER_PAGE);
    
    // 第一頁沒有分頁狀態
    if (pagingState != null)
    {     
      st.setPagingState(pagingState);
    }
    
    ResultSet rs = session.execute(st);
    result.put("pagingState", rs.getExecutionInfo().getPagingState());
    
    //請注意,我們不依賴RESULTS_PER_PAGE,因為fetch size并不意味著cassandra總是返回準確的結果集
    //它可能返回比fetch size稍微多一點或者少一點,另外,我們可能在結果集的結尾
    int remaining = rs.getAvailableWithoutFetching();
    for (Row row : rs)
    {
      Teacher teacher = this.obtainTeacherFromRow(row);
      teachers.add(teacher);
      
      if (--remaining == 0)
      {
        break;
      }
    }
    result.put("teachers", teachers);
    return result;
  }
 
  private Teacher obtainTeacherFromRow(Row row)
  {
    Teacher teacher = new Teacher();
    teacher.setAddress(row.getString("address"));
    teacher.setAge(row.getInt("age"));
    teacher.setHeight(row.getInt("height"));
    teacher.setId(row.getInt("id"));
    teacher.setName(row.getString("name"));
    
    return teacher;
  }
 
}

測試代碼:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import java.util.Map;
 
import com.datastax.driver.core.PagingState;
import com.huawei.cassandra.dao.ICassandraPage;
import com.huawei.cassandra.dao.impl.CassandraPageDao;
 
public class PagingTest
{
  
  public static void main(String[] args)
  {
    ICassandraPage cassPage = new CassandraPageDao();
    Map<String, Object> result = cassPage.page(null);
    PagingState pagingState = (PagingState) result.get("pagingState");
    System.out.println(result.get("teachers"));
    while (pagingState != null)
    {
      // PagingState對象可以被序列化成字符串或字節數組
      System.out.println("==============================================");
      result = cassPage.page(pagingState);
      pagingState = (PagingState) result.get("pagingState");
      System.out.println(result.get("teachers"));
    }
  }
  
}

我們來看看Statement的setPagingState(pagingState)方法:

java實現cassandra高級操作之分頁實例(有項目具體需求)

四、偏移查詢

保存分頁狀態,能夠保證從某一頁移動到下一頁很好地運行(也可以實現上一頁),但是它不滿足隨機跳躍,比如直接跳到第10頁,因為我們不知道第10頁的前一頁的分頁狀態。像這樣需要偏移查詢的特點,并不被cassandra原生支持,理由是偏移查詢效率低下(性能與跳過的行數呈線性反比),所以cassandra官方不鼓勵使用偏移量。如果非要實現偏移查詢,我們可以在客戶端模擬實現。但是性能還是呈線性反比,也就說偏移量越大,性能越低,如果性能在我們的接受范圍內,那還是可以實現的。例如,每一頁顯示10行,最多顯示20頁,這就意味著,當顯示第20頁的時候,最多需要額外的多抓取190行,但這也不會對性能造成太大的降低,所以數據量不大的話,模擬實現偏移查詢還是可以的。

舉個例子,假設每頁顯示10條記錄,fetch size 是50,我們請求第12頁(也就是第110行到第119行):

1、第一次執行查詢,結果集包含0到49行,我們不需要用到它,只需要分頁狀態;

2、用第一次查詢得到的分頁狀態,執行第二次查詢;

3、用第二次查詢得到的分頁狀態,執行第三次查詢。結果集包含100到149行;

4、用第三次查詢得到的結果集,先過濾掉前10條記錄,然后讀取10條記錄,最后丟棄剩下的記錄,讀取的10條記錄則是第12頁需要顯示的記錄。

我們需要嘗試著找到最佳的fetch size來達到最佳平衡:太小就意味著后臺更多的查詢;太大則意味著返回了更大的信息量以及更多不需要的行。

另外,cassandra本身不支持偏移量查詢。在滿足性能的前提下,客戶端模擬偏移量的實現只是一種妥協。官方建議如下:

1、使用預期的查詢模式來測試代碼,以確保假設是正確的

2、設置最高頁碼的硬限制,以防止惡意用戶觸發跳過大量行的查詢

五、總結

Cassandra對分頁的支持有限,上一頁、下一頁比較好實現。不支持偏移量的查詢,硬要實現的話,可以采用客戶端模擬的方式,但是這種場景最好不要用在cassandra上,因為cassandra一般而言是用來解決大數據問題,而偏移量查詢一旦數據量太大,性能就不敢恭維了。

在我的項目中,索引修復用到了cassandra的分頁,場景如下:cassandra的表不建二級索引,用elasticsearch實現cassandra表的二級索引,那么就會涉及到索引的一致性修復的問題,這里就用到了cassandra的分頁,對cassandra的某張表進行全表遍歷,逐條與elasticsearch中的數據進行匹對,若elasticsearch中不存在,則在elasticsearch中新增,若存在而又不一致,則在elasticsearch中修復。具體elasticsearch怎么樣實現cassandra的索引功能,在我后續博客中會專門的講解,這里就不多說了。而在cassandra表進行全表遍歷的時候就需要用到分頁,因為表中數據量太大,億級別的數據不可能一次全部加載到內存中。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。

原文鏈接:http://www.cnblogs.com/youzhibing/p/6653129.html

延伸 · 閱讀

精彩推薦
Weibo Article 1 Weibo Article 2 Weibo Article 3 Weibo Article 4 Weibo Article 5 Weibo Article 6 Weibo Article 7 Weibo Article 8 Weibo Article 9 Weibo Article 10 Weibo Article 11 Weibo Article 12 Weibo Article 13 Weibo Article 14 Weibo Article 15 Weibo Article 16 Weibo Article 17 Weibo Article 18 Weibo Article 19 Weibo Article 20 Weibo Article 21 Weibo Article 22 Weibo Article 23 Weibo Article 24 Weibo Article 25 Weibo Article 26 Weibo Article 27 Weibo Article 28 Weibo Article 29 Weibo Article 30 Weibo Article 31 Weibo Article 32 Weibo Article 33 Weibo Article 34 Weibo Article 35 Weibo Article 36 Weibo Article 37 Weibo Article 38 Weibo Article 39 Weibo Article 40
主站蜘蛛池模板: 一区二区三区亚洲 | 欧美aⅴ| 精品成人在线 | 日韩精品视频在线播放 | 国产一区二区三区在线免费观看 | 亚洲区视频在线观看 | 九九热精品国产 | 亚洲成年人网站在线观看 | 骚视频网站 | 欧美一级c片 | 日韩成人免费电影 | 毛片一区| 五月天一区二区 | 久久久成人网 | 福利网在线 | 搡女人真爽免费午夜网站 | 黄色电影免费在线观看 | 欧美精品成人一区二区在线 | 亚洲一区在线视频 | 日韩一区二区三区在线 | 欧美不卡一区二区三区 | 午夜激情视频网站 | 91最新网址 | 欧美一级欧美三级在线观看 | 国产h片在线观看 | 九九只有精品 | 国产精品不卡在线播放 | 欧美日韩成人在线 | 欧美自拍一区 | 午夜免费小视频 | 伊人6| 欧美一区二区在线视频 | 黄色mm视频 | 欧美视频二区 | 久久国产99 | 国产色 | 午夜网| 久久久久久久一区 | 亚洲一区二区中文字幕 | 国产精品第一国产精品 | 91av在线免费播放 |