Topik ini menjelaskan skenario yang cocok untuk fitur sharding dan cara menggunakannya.
Informasi latar belakang
Dalam logika bisnis, Tabel A digunakan untuk menyimpan data bisnis. Untuk menggunakan Tabel B guna menyimpan data tersebut, Anda dapat memodifikasi konfigurasinya.
Sharding
Dalam sebagian besar skenario bisnis, hanya data yang dihasilkan dalam minggu sebelumnya yang sering diakses. Anda dapat membuat satu tabel setiap minggu untuk menyimpan data terbaru. Pendekatan ini memungkinkan Anda melakukan kueri data panas secara efisien. Namun, Anda harus membuat dan menghapus tabel secara manual, yang meningkatkan kompleksitas logika bisnis.
Skenario
Mengelola data deret waktu
Jika data bisnis Anda sensitif terhadap waktu, Anda dapat membuat beberapa indeks berdasarkan waktu. Hal ini mengurangi ukuran satu indeks dan meningkatkan kinerja kueri. Selama proses ini, Anda tidak perlu membuat atau menghapus indeks secara manual.
Membangun ulang indeks
Anda dapat membangun ulang indeks tanpa memengaruhi kueri data berbasis indeks yang sudah ada. Setelah indeks dibangun ulang, indeks baru akan digunakan untuk melakukan kueri data. Selama proses ini, Anda tidak perlu memodifikasi kode yang sudah ada.
Buat alias untuk koleksi yang ada
curl "http://solrhost:8983/solr/admin/collections?action=CREATEALIAS&name=your_alias_name&collections=your_collection_name_A" URL di atas menunjukkan: Buat alias bernama your_allias_name yang mengarah ke koleksi your_collection_name_A. Dalam logika bisnis Anda, Anda cukup mengakses your_alias_name, dan kernel akan secara otomatis meneruskan permintaan ke koleksi aktual.
Untuk mengalihkan akses ke koleksi your_collection_name_B, jalankan perintah untuk memperbarui alias tersebut.
curl "http://solrhost:8983/solr/admin/collections?
action=ALIASPROP&name=your_alias_name&collections=your_collection_name_B" Anda dapat mengakses koleksi baru tanpa melakukan perubahan apa pun pada kode bisnis Anda.
Pembagian tabel otomatis
LindormSearch dapat secara otomatis membuat koleksi berdasarkan nilai dalam bidang waktu. Hal ini membantu menyederhanakan logika bisnis. Contoh berikut menunjukkan cara mengonfigurasi sistem untuk membuat satu koleksi setiap minggu dan secara otomatis menghapus koleksi yang telah kedaluwarsa.
curl "http://solrhost:8983/solr/admin/collections?action=CREATEALIAS&name=test_router_alias&router.start=NOW-30DAYS/DAY&router.autoDeleteAge=/DAY-90DAYS&router.field=your_timestamp_l&router.name=time&router.interval=%2B7DAY&router.maxFutureMs=8640000000&create-collection.collection.configName=_indexer_default&create-collection.numShards=2" Parameter | Nilai contoh | Deskripsi |
router.start | NOW-30DAYS/DAY | Awal rentang waktu untuk koleksi pertama. Dalam contoh ini, NOW-30DAYS/DAY menunjukkan bahwa waktu mulai adalah 30 hari sebelum waktu saat ini. |
router.interval | +7DAY | Interval pembuatan koleksi baru. Dalam contoh ini, koleksi baru dibuat setiap tujuh hari. |
router.autoDeleteAge | /DAY-90DAYS | Periode waktu penyimpanan koleksi sebelum koleksi tersebut dihapus secara otomatis. Dalam contoh ini, nilai tersebut menunjukkan bahwa sistem akan secara otomatis menghapus koleksi yang telah disimpan selama 90 hari. Nilai parameter ini harus lebih besar daripada nilai parameter router.start. |
router.field | your_timestamp_l | Bidang waktu yang digunakan untuk membuat koleksi. Secara default, bidang ini dengan nilai yang ditentukan harus disertakan dalam data bisnis. Misalnya, Anda dapat mengatur nilainya ke System.currentTimeMillis(). Nilai ini merupakan timestamp sistem saat ini. |
router.maxFutureMs | 8640000000 | Selisih maksimum yang diizinkan antara nilai bidang your_date_dt dan waktu saat ini. Parameter ini memastikan bahwa hanya data yang dihasilkan dalam rentang waktu tertentu yang ditulis ke koleksi. Dalam contoh ini, nilai parameter ini menunjukkan bahwa hanya data yang dihasilkan dalam 100 hari sebelumnya atau 100 hari berikutnya yang dapat ditulis ke koleksi. |
collection.collection.configName | _indexer_default | Set konfigurasi tempat koleksi bergantung. Anda dapat mengatur parameter ini ke nama set konfigurasi Anda. Untuk informasi selengkapnya, lihat Perbarui set konfigurasi. |
create-collection.numShards | 2 | Jumlah shard yang dibuat untuk koleksi. Nilai default: 2. |
Konfigurasi di atas berarti: Mulai dari 30 hari yang lalu (misalnya hari ini tanggal 7 Maret), buat indeks setiap 7 hari menggunakan bidang your_timestamp_l. Nilai bidang tersebut harus berada dalam rentang 100 hari dari waktu saat ini, dan sistem akan secara berkala menghapus indeks yang telah kedaluwarsa 90 hari lalu.
Gambar berikut menunjukkan hasilnya:

Data bisnis harus berisi bidang waktu. Tipe data bidang waktu dapat berupa DATE atau LONG.
Secara default, semua koleksi akan dikueri. Anda dapat menentukan koleksi tertentu untuk dikueri dengan menjalankan perintah curl menggunakan URL tertentu atau memanggil operasi API untuk mengambil daftar semua koleksi. Kemudian, Anda dapat memperoleh nilai bidang waktu dari koleksi tersebut dan menentukan koleksi yang akan dikueri. Untuk informasi selengkapnya, lihat contoh kode berikut.
Hapus alias
Untuk menghapus alias biasa, jalankan perintah berikut:
curl "http://solrhost:8983/solr/admin/collections?action=DELETEALIAS&name=your_alias_name" Untuk menghapus alias dengan sharding tabel otomatis, Anda juga perlu menghapus koleksi yang terkait secara aktif.
Dapatkan daftar koleksi yang terkait dengan alias tersebut.
curl "http://solrhost:8983/solr/admin/collections?action=LIST"Koleksi dengan nama yang dimulai dengan
test_router_aliassemuanya terkait dengan alias ini.Hapus alias tersebut.
curl "http://solrhost:8983/solr/admin/collections?action=DELETEALIAS&name=test_router_alias"Hapus semua koleksi.
curl "http://solrhost:8983/solr/admin/collections?action=DELETE&name=collection_name"
Referensi
CREATEALIAS: CREATEALIAS
LIST: LIST
Cara melakukan kueri menggunakan tipe waktu LONG
import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.impl.CloudSolrClient;
import org.apache.solr.client.solrj.impl.ClusterStateProvider;
import org.apache.solr.client.solrj.response.QueryResponse;
import org.apache.solr.common.SolrDocument;
import org.apache.solr.common.util.StrUtils;
import java.time.Instant;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.time.temporal.ChronoField;
import java.util.AbstractMap;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Optional;
public class SolrDemo {
private static final DateTimeFormatter DATE_TIME_FORMATTER = new DateTimeFormatterBuilder()
.append(DateTimeFormatter.ISO_LOCAL_DATE).appendPattern("[_HH[_mm[_ss]]]")
.parseDefaulting(ChronoField.HOUR_OF_DAY, 0)
.parseDefaulting(ChronoField.MINUTE_OF_HOUR, 0)
.parseDefaulting(ChronoField.SECOND_OF_MINUTE, 0)
.toFormatter(Locale.ROOT).withZone(ZoneOffset.UTC);
private static final String zkHost = "localhost:2181/solr";
private CloudSolrClient cloudSolrClient;
private ClusterStateProvider clusterStateProvider;
public SolrDemo() {
cloudSolrClient = new CloudSolrClient.Builder(
Collections.singletonList(zkHost), Optional.empty()).build();
cloudSolrClient.connect();
clusterStateProvider = cloudSolrClient.getClusterStateProvider();
}
public void close() throws Exception {
if (null != cloudSolrClient) {
cloudSolrClient.close();
}
}
private List<String> findCollection(String aliasName, long start, long end) {
List<String> collections = new ArrayList<>();
if (start > end) {
return collections;
}
// Temukan koleksi yang sesuai berdasarkan [start, end]
if (clusterStateProvider.getState(aliasName) == null) {
// Dapatkan semua daftar koleksi yang sesuai dengan aliasName saat ini
// test_router_alias_2020-03-04, test_router_alias_2020-02-26, test_router_alias_2020-02-19, test_router_alias_2020-02-12, test_router_alias_2020-02-05
List<String> aliasedCollections = clusterStateProvider.resolveAlias(aliasName);
// Ekstrak tanggal dan waktu dari nama koleksi
// 2020-03-04T00:00:00Z=test_router_alias_2020-03-04,
// 2020-02-26T00:00:00Z=test_router_alias_2020-02-26,
// 2020-02-19T00:00:00Z=test_router_alias_2020-02-19,
// 2020-02-12T00:00:00Z=test_router_alias_2020-02-12,
// 2020-02-05T00:00:00Z=test_router_alias_2020-02-05
List<Map.Entry<Instant, String>> collectionsInstant = new ArrayList<>(aliasedCollections.size());
for (String collectionName : aliasedCollections) {
String dateTimePart = collectionName.substring(aliasName.length() + 1);
Instant instant = DATE_TIME_FORMATTER.parse(dateTimePart, Instant::from);
collectionsInstant.add(new AbstractMap.SimpleImmutableEntry<>(instant, collectionName));
}
// Temukan koleksi yang sesuai berdasarkan waktu kueri
Instant startI = Instant.ofEpochMilli(start);
Instant endI = Instant.ofEpochMilli(end);
for (Map.Entry<Instant, String> entry : collectionsInstant) {
Instant colStartTime = entry.getKey();
if (!endI.isBefore(colStartTime)) {
collections.add(entry.getValue());
System.out.println("temukan koleksi: " + entry.getValue());
if (!startI.isBefore(colStartTime)) {
break;
}
}
}
} else {
collections.add(aliasName);
}
System.out.println("kueri " + collections);
return collections;
}
public void run() throws Exception {
try {
// [2020-03-07 2020-03-10]
long start = 1583538686312L;
long end = 1583797886000L;
String aliasName = "test_router_alias";
String collections = StrUtils.join(findCollection(aliasName, start, end), ',');
QueryResponse res = cloudSolrClient.query(collections, new SolrQuery("*:*"));
for (SolrDocument sd : res.getResults()) {
System.out.println(sd.get("id") + " " + sd.get("gmtCreate_l"));
}
} finally {
cloudSolrClient.close();
}
}
public static void main(String[] args) throws Exception {
SolrDemo solrDemo = new SolrDemo();
solrDemo.run();
solrDemo.close();
}
}